Files
docuseal/lib/time_utils.rb
T

143 lines
3.5 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
module TimeUtils
2023-12-17 23:32:05 +02:00
MONTH_FORMATS = {
'M' => '%-m',
'MM' => '%m',
'MMM' => '%b',
'MMMM' => '%B'
}.freeze
DAY_FORMATS = {
'D' => '%-d',
'DD' => '%d'
}.freeze
YEAR_FORMATS = {
'YYYY' => '%Y',
2024-05-10 09:23:22 +03:00
'YYY' => '%Y',
2023-12-17 23:32:05 +02:00
'YY' => '%y'
}.freeze
2026-04-23 20:25:41 +03:00
HOUR_FORMATS = {
'H' => '%-H',
'HH' => '%H',
'h' => '%-I',
'hh' => '%I'
}.freeze
MINUTE_FORMATS = {
'm' => '%-M',
'mm' => '%M'
}.freeze
SECOND_FORMATS = {
's' => '%-S',
'ss' => '%S'
}.freeze
AMPM_FORMATS = {
'A' => '%p',
'a' => '%P'
}.freeze
TIMEZONE_FORMATS = {
'z' => '%Z'
}.freeze
TIME_FORMATS = HOUR_FORMATS.merge(MINUTE_FORMATS)
.merge(SECOND_FORMATS)
.merge(AMPM_FORMATS)
.freeze
ALL_FORMATS = MONTH_FORMATS.merge(DAY_FORMATS)
.merge(YEAR_FORMATS)
.merge(TIME_FORMATS)
.merge(TIMEZONE_FORMATS)
.freeze
TOKEN_REGEX = /MMMM|MMM|MM|M|DD|D|YYYY|YYY|YY|HH|hh|H|h|mm|m|ss|s|A|a|z/
MONTH_ONLY_VALUE_REGEX = /\A\d{4}-\d{2}\z/
2023-12-17 23:32:05 +02:00
DEFAULT_DATE_FORMAT_US = 'MM/DD/YYYY'
DEFAULT_DATE_FORMAT = 'DD/MM/YYYY'
2025-11-21 17:50:04 +02:00
US_TIMEZONES = %w[EST EDT CST CDT MST MDT PST PDT HST HDT AKST AKDT].freeze
2024-11-23 01:45:10 +02:00
module_function
def timezone_abbr(timezone, time = Time.current)
tz_info = TZInfo::Timezone.get(
ActiveSupport::TimeZone::MAPPING[timezone] || timezone || 'UTC'
)
tz_info.abbreviation(time)
end
2023-12-17 23:32:05 +02:00
2024-08-01 16:43:55 +03:00
def parse_time_value(value)
if value.is_a?(Integer)
Time.zone.at(value.to_s.first(10).to_i)
elsif value.present?
Time.zone.parse(value)
end
end
2026-04-23 20:25:41 +03:00
def format_with_time?(format)
format.to_s.match?(/[HhAasz]/)
end
2024-06-10 12:08:56 +03:00
2026-04-23 20:25:41 +03:00
def month_only_format?(format)
format.to_s.present? && !format.to_s.match?(/[DdHhAasz]/)
2024-06-10 12:08:56 +03:00
end
2026-04-23 20:25:41 +03:00
def format_date_preview(format, locale, timezone)
return '' if format.blank?
2023-12-17 23:32:05 +02:00
2026-04-23 20:25:41 +03:00
format = format.upcase unless format_with_time?(format)
preview_pattern = format.gsub(TOKEN_REGEX) { |token| TIME_FORMATS.key?(token) ? '--' : ALL_FORMATS[token] }
I18n.l(Time.current.in_time_zone(timezone.presence || Time.zone.name), format: preview_pattern, locale:)
end
2025-06-19 12:25:35 +03:00
2026-04-23 20:25:41 +03:00
def current_date_value(format, timezone)
tz = timezone.presence || Time.zone.name
if format_with_time?(format)
Time.current.utc.iso8601
elsif month_only_format?(format)
Time.current.in_time_zone(tz).strftime('%Y-%m')
else
Time.current.in_time_zone(tz).to_date.to_s
end
end
def parse_date_string(string, pattern)
with_time = format_with_time?(pattern)
pattern = pattern.upcase unless with_time
pattern = pattern.gsub(TOKEN_REGEX, ALL_FORMATS)
with_time ? Time.zone.strptime(string, pattern) : Date.strptime(string, pattern)
end
def format_date_string(string, format, locale, timezone: nil)
format = format.upcase if format && !format_with_time?(format)
2023-12-17 23:32:05 +02:00
format ||= locale.to_s.ends_with?('US') ? DEFAULT_DATE_FORMAT_US : DEFAULT_DATE_FORMAT
2026-04-23 20:25:41 +03:00
date =
if format_with_time?(format)
Time.iso8601(string.to_s).in_time_zone(timezone.presence || Time.zone.name)
elsif string.to_s.match?(MONTH_ONLY_VALUE_REGEX)
year, month = string.to_s.split('-').map(&:to_i)
Date.new(year, month, 1)
else
Date.parse(string.to_s)
end
2023-12-17 23:32:05 +02:00
2026-04-23 20:25:41 +03:00
I18n.l(date, format: format.gsub(TOKEN_REGEX, ALL_FORMATS), locale:)
rescue ArgumentError
2023-12-17 23:32:05 +02:00
string
end
end