Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Limits on UTC offset #272

Closed
lpsmith opened this issue Jul 21, 2015 · 2 comments
Closed

Limits on UTC offset #272

lpsmith opened this issue Jul 21, 2015 · 2 comments

Comments

@lpsmith
Copy link
Contributor

lpsmith commented Jul 21, 2015

I'll admit this issue is a bit of a judgement call, but the limits being imposed on the utc offset may be a teensy bit too strict.

The IANA tz database has (at least) eight time zones that have exceeded the current -12 to +14 limit: Asia/Manila, Pacific/Guam and Pacific/Saipan before 1844-12-31, as well as America/Metlakatla, America/Juneau, America/Sitka, America/Yakutat, and America/Anchorage before 1867-10-18. But, assuming I'm not missing something, it does appear that this limit is valid since 1868.

However, the IANA tz offsets before the respective dates are all local mean time, which means most of them are not offset an integer number of minutes from UTC. So one could argue that loosening the limit isn't all that meaningful without also supporting ±HH:MM:SS offsets.

So, for whatever it's worth here's some example syntax that PostgreSQL will generate, based on the tz database:

psql (9.4.4)
Type "help" for help.

lpsmith=> set timezone to 'Pacific/Guam';
SET
lpsmith=> values ('1844-12-31 14:20:59+00'::timestamptz),
lpsmith->        ('1844-12-31 14:21:00+00'::timestamptz);
          column1          
---------------------------
 1844-12-30 23:59:59-14:21
 1845-01-01 00:00:00+09:39
(2 rows)

lpsmith=> set timezone to 'America/Metlakatla';
SET
lpsmith=> values ('1867-10-17 08:46:17+00'::timestamptz),
lpsmith->        ('1867-10-17 08:46:18+00'::timestamptz);
           column1            
------------------------------
 1867-10-17 23:59:59+15:13:42
 1867-10-17 00:00:00-08:46:18
(2 rows)

And the ±HH:MM:SS syntax is not limited to obscure timezones; indeed almost every IANA timezone will generate it:

lpsmith=> set timezone to 'America/Los_Angeles';
SET
lpsmith=> values ('1883-11-18 19:59:59+00'::timestamptz),
lpsmith->        ('1883-11-18 20:00:00+00'::timestamptz);
           column1            
------------------------------
 1883-11-18 12:07:01-07:52:58
 1883-11-18 12:00:00-08
(2 rows)

And as far as I can tell, the following is the most recent timestamp that will be generated with the ±HH:MM:SS syntax:

lpsmith=> set timezone to 'Africa/Monrovia';
SET
lpsmith=> values ('1972-05-01 00:44:29+00'::timestamptz),
lpsmith->        ('1972-05-01 00:44:30+00'::timestamptz);
           column1            
------------------------------
 1972-04-30 23:59:59-00:44:30
 1972-05-01 00:44:30+00
(2 rows)
@phadej
Copy link
Collaborator

phadej commented Jun 15, 2023

The offset limits are right there since the introduction in c156e91. I cannot find a reasoning to these limits.

The parser in https://ijmacd.github.io/rfc3339-iso8601/ accepts e.g. 2023-06-15T16:25:00-23:59

ISO8601 and RFC3339 don't allow seconds in the offsets, and I'm not sure we should either.

-23:59 is allowed as e.g. RFC grammar is

date-fullyear   = 4DIGIT
   date-month      = 2DIGIT  ; 01-12
   date-mday       = 2DIGIT  ; 01-28, 01-29, 01-30, 01-31 based on
                             ; month/year
   time-hour       = 2DIGIT  ; 00-23
   time-minute     = 2DIGIT  ; 00-59
   time-second     = 2DIGIT  ; 00-58, 00-59, 00-60 based on leap second
                             ; rules
   time-secfrac    = "." 1*DIGIT
   time-numoffset  = ("+" / "-") time-hour ":" time-minute
   time-offset     = "Z" / time-numoffset

   partial-time    = time-hour ":" time-minute ":" time-second
                     [time-secfrac]
   full-date       = date-fullyear "-" date-month "-" date-mday
   full-time       = partial-time time-offset

   date-time       = full-date "T" full-time

note time-hour (00-23) and time-minute (00-59) in time-numoffset production. I cannot find mentions for the limits in the prose. I don't have ISO8601 available to read.

@phadej
Copy link
Collaborator

phadej commented Jun 15, 2023

OTOH, time allows full digits:

Prelude Data.Time> parseTimeM True defaultTimeLocale "%Z" "+99:99" :: Maybe TimeZone 
Just +10039

python3.6 seems to have 23:59 as a limit

>>> datetime.datetime.strptime("Tue May 08 15:14:45 +2359 2012","%a %b %d %H:%M:%S %z %Y")
datetime.datetime(2012, 5, 8, 15, 14, 45, tzinfo=datetime.timezone(datetime.timedelta(0, 86340)))
>>> datetime.datetime.strptime("Tue May 08 15:14:45 +2360 2012","%a %b %d %H:%M:%S %z %Y")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.6/_strptime.py", line 565, in _strptime_datetime
    tt, fraction = _strptime(data_string, format)
  File "/usr/lib/python3.6/_strptime.py", line 362, in _strptime
    (data_string, format))
ValueError: time data 'Tue May 08 15:14:45 +2360 2012' does not match format '%a %b %d %H:%M:%S %z %Y'
>>> datetime.datetime.strptime("Tue May 08 15:14:45 +2459 2012","%a %b %d %H:%M:%S %z %Y")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.6/_strptime.py", line 573, in _strptime_datetime
    tz = datetime_timezone(tzdelta)
ValueError: offset must be a timedelta strictly between -timedelta(hours=24) and timedelta(hours=24), not datetime.timedelta(1, 3540).

@phadej phadej closed this as completed in 3774a8d Jun 20, 2023
phadej added a commit that referenced this issue Jun 20, 2023
Resolve #272. Allow 23:59 as maximum/minimum tz offset
JonathanLorimer pushed a commit to JonathanLorimer/aeson that referenced this issue Aug 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants