Tcl Source Code

View Ticket
Login
Ticket UUID: dc69e5ecf04313429fd202b1906cd85bb7888f95
Title: [clock scan] does not recognize AKST or AKDT
Type: Bug Version: 8.6.8
Submitter: andy Created on: 2018-05-21 21:06:42
Subsystem: 16. Commands A-H Assigned To: nobody
Priority: 5 Medium Severity: Important
Status: Open Last Modified: 2018-05-29 18:06:40
Resolution: None Closed By: nobody
    Closed on:
Description: (text/html)
<p>[clock format -timezone :America/Anchorage] produces a timezone string of AKDT or AKST, neither of which is supported by [clock scan].  This affects both the legacy freeform and the new parsers.</p>

<pre>
% clock format [clock seconds] -timezone :America/Anchorage
Mon May 21 11:53:41 AKDT 2018
% clock scan "Mon May 21 11:53:41 AKDT 2018"
unable to convert date-time string "Mon May 21 11:53:55 AKDT 2018": syntax error (characters 19-23)
% clock scan "Mon May 21 11:53:55 AKDT 2018" -format "%a %b %d %H:%M:%S %z %Y"
time zone "akdt" not found
% dict set ::tcl::clock::LegacyTimeZone akdt -0800
% clock scan "Mon May 21 11:53:55 AKDT 2018" -format "%a %b %d %H:%M:%S %z %Y"
1526932435
</pre>

<p>As shown above, the new parser can be patched by editing $LegacyTimeZone:</p>

<pre>
dict set ::tcl::clock::LegacyTimeZone akdt -0800
dict set ::tcl::clock::LegacyTimeZone akst -0900
</pre>

<p>The legacy parser can only be fixed by editing tclGetDate.y.</p>

<ul><li><a href="http://core.tcl.tk/tcl/artifact/7159dd873c567e10?ln=534-622">New parser</a></li>
<li><a href="http://core.tcl.tk/tcl/artifact/7b3b76f504f8c46f?ln=592-671">Legacy parser</a></li></ul>

<p>Side note: while researching this issue, I noticed several timezones named zp[456] which do not work in the legacy freeform parser due to TclDatelex() not recognizing the trailing digit as part of the token.  Not knowing anything about these timezones, I don't feel qualified to file a separate ticket on them.  If any work is done in this area, I would also suggest confirming that all timezone strings that can be generated by [clock format] can also be recognized by [clock scan] using both the legacy freeform and new Tcl parsers.</p>
User Comments: sebres added on 2018-05-29 18:06:40: (text/x-fossil-wiki)
I've rebased (back-ported) my tclclockmod back to tcl.core in branch "sebres-8-6-clock-speedup-cr2", where this issue is partially fixed in [deec2700e3] (AKST/AKDT only).

Complete fix follows (if I get cleared all lacks of abbreviation, and resolved all conflicts with most popular/usual abbreviations).

andy (claiming to be Andy Goth) added on 2018-05-28 22:57:18:
Thank you for your research.  It's clear I really ought to amend my code to either write UTC time or a numeric time zone offset.  I was simply using the default [clock format] format, but that can be easily changed.  Your work is welcome, but if you're hitting ambiguities, it will be problematic no matter what is done.

sebres added on 2018-05-25 19:43:26: (text/x-fossil-wiki)
When tinkering round about time-zones abbreviations (which conflict more and more), I've even more questions...

@Peter da Silva, @Karl Lehenbauer, @flightaware: <ul>
<li>  How do you handle such confusions by the different time-zones with the same abbreviation by the flight tracking or similar services?</li></ul>

@Chinese Tclers: <ul>
<li>  How you resolve such conflicts, e. g. with CST-abbreviation by string as date interpolation? 
<li>  Using custom time-zones files?</li>
<li>  Somehow else?</li></ul>

For example, I mean the "CST" abbreviation (as provided from iana-tzdb, therefore in TCL also):<ul>
<li>"CST" - "Central Standard Time" ("America/Chicago", etc.)</li>
<li>"CST" - "Central Standard Time (with 1 hour offset)" ("America/Havana")</li>
<li>"CST" - "China Standard Time" ("Asia/Shanghai", "Asia/Taipei", etc.) </li>
</ul>

So forwards-backwards conversion test like this:
<code><pre style="padding-left:15pt">
set tm [clock scan "01/01/2018" -gmt 1]
puts "utc: $tm, [clock format $tm -g 1 -l en]"
set testtz {
  :America/Chicago   {CST}
  CST6               {CST}
  :America/Havana  {CST+1}
  CST5             {CST+1}
  :Asia/Shanghai  {CST+14}
  :Asia/Taipei    {CST+14}
  CST-8           {CST+14}
}
# direct forward - backwards:
foreach {tz alt_tz} $testtz {
  puts "[format %20s $tz]: [set str [clock format $tm -timezone $tz -l en]] \
  \t--> [set tm2 [clock scan $str]] = [clock format $tm2 -g 1 -l en]"
}
# show alternative (does not work in tcl.core, currently tclclockmod only):
puts "# alternatives:"
foreach {tz alt_tz} $testtz {
  set str [clock format $tm -timezone $tz -l en]
  set str [string map [list CST $alt_tz] $str]
  puts "[format %20s $tz]: $str \
  \t--> [set tm2 [clock scan $str]] = [clock format $tm2 -g 1 -l en]"
}
</pre></code>
results to:
<code><pre style="padding-left:15pt">
utc: 1514764800, Mon Jan 01 00:00:00 GMT 2018<small style="color:green">
    :America/Chicago: Sun Dec 31 18:00:00 CST 2017      --> 1514764800 = Mon Jan 01 00:00:00 GMT 2018
                CST6: Sun Dec 31 18:00:00 CST 2017      --> 1514764800 = Mon Jan 01 00:00:00 GMT 2018</small><small style="color:blue">
     :America/Havana: Sun Dec 31 19:00:00 CST 2017      --> <b>1514768400</b> = Mon Jan 01 <b>01:00:00</b> GMT 2018
                CST5: Sun Dec 31 19:00:00 CST 2017      --> <b>1514768400</b> = Mon Jan 01 <b>01:00:00</b> GMT 2018</small><small style="color:red">
      :Asia/Shanghai: Mon Jan 01 08:00:00 CST 2018      --> <b>1514815200</b> = Mon Jan 01 <b>14:00:00</b> GMT 2018
        :Asia/Taipei: Mon Jan 01 08:00:00 CST 2018      --> <b>1514815200</b> = Mon Jan 01 <b>14:00:00</b> GMT 2018
               CST-8: Mon Jan 01 08:00:00 CST 2018      --> <b>1514815200</b> = Mon Jan 01 <b>14:00:00</b> GMT 2018</small>
# alternatives:<small style="color:green">
    :America/Chicago: Sun Dec 31 18:00:00 CST 2017      --> 1514764800 = Mon Jan 01 00:00:00 GMT 2018
                CST6: Sun Dec 31 18:00:00 CST 2017      --> 1514764800 = Mon Jan 01 00:00:00 GMT 2018</small><small style="color:blue">
     :America/Havana: Sun Dec 31 19:00:00 CST+1 2017    --> 1514764800 = Mon Jan 01 00:00:00 GMT 2018
                CST5: Sun Dec 31 19:00:00 CST+1 2017    --> 1514764800 = Mon Jan 01 00:00:00 GMT 2018</small><small style="color:red">
      :Asia/Shanghai: Mon Jan 01 08:00:00 CST+14 2018   --> 1514764800 = Mon Jan 01 00:00:00 GMT 2018
        :Asia/Taipei: Mon Jan 01 08:00:00 CST+14 2018   --> 1514764800 = Mon Jan 01 00:00:00 GMT 2018
               CST-8: Mon Jan 01 08:00:00 CST+14 2018   --> 1514764800 = Mon Jan 01 00:00:00 GMT 2018</small>
</pre></code>

@Everyone: <ul>
<li>  Had someone already such issues at all?</li>
<li>  Do we have a "bug" in clock module (format resp. scan) for several zones?</li>
<li>  Should we fix the abbreviations for several zones (leave most popular/usual unchanged, replace others with another abbreviations or/and offsets)?</li></ul>

sebres added on 2018-05-25 13:24:59: (text/x-fossil-wiki)
So currently tried to manipulate tools/tclZIC.tcl to cumulate all shortcut-zones with dst/offset to build a map (excepting etc-zones) from current iana-tzdb, below is the result.

As you can see (and as been expecting) several zones have different offsets, therefore I tend to build regular TZ-files for the shortcut zones (similar CET, etc), so within valid time intervals for it.

<code><pre><small style="font-size:50%">
legacy_zones = {
  {"HDT", 1 -32400, 1 -34200},
  {"MWT", 1 -21600},
  {"MPT", 1 -21600},
  {"MDDT", 1 -18000},
  {"SST", 0 -39600},
  {"HKST", 1 32400},
  {"SET", 0 3614},
  {"ACDT", 1 37800},
  {"KMT", 0 -18430, 0 7324, 0 5736},
  {"FFMT", 0 -14660},
  {"PKT", 0 18000},
  {"CDDT", 1 -14400},
  {"MDST", 1 16279},
  {"PDT", 1 -25200},
  {"ADT", 1 -10800, 0 -10800},
  {"PKST", 1 21600},
  {"LST", 1 9394},
  {"ACST", 0 32400, 0 34200, 0 37800},
  {"MSD", 0 10800, 1 14400, 0 14400},
  {"SMT", 0 -16966, 0 24925, 0 -13884, 0 8160},
  {"PDDT", 1 -21600},
  {"AKDT", 1 -28800},
  {"YWT", 1 -28800},
  {"DMT", 0 -1521},
  {"WITA", 0 28800},
  {"EDT", 1 -14400, 0 -14400},
  {"YPT", 1 -28800},
  {"SJMT", 0 -20173},
  {"WAST", 1 7200},
  {"PST", 0 -28800},
  {"NZDT", 1 46800},
  {"WMT", 0 5040},
  {"CAT", 0 7200},
  {"AST", 0 -36000, 0 -14400},
  {"IDT", 1 10800},
  {"HMT", 0 -19776, 0 21200, 0 -6872, 0 5989},
  {"EEST", 1 10800, 0 10800, 0 7200},
  {"NWT", 1 -36000, 0 -9000},
  {"NPT", 1 -36000, 1 -9000},
  {"MSK", 0 10800, 0 14400},
  {"WEST", 1 3600, 0 3600, 0 7200, 1 7200},
  {"AKST", 0 -32400},
  {"ADDT", 1 -7200},
  {"LMT", 0 -968, 0 -52, 0 732, 0 -3740, 0 7509, 0 -1820, 0 -1276, 0 -3168, 0 6720, 0 7588, 0 7808, 0 816, 0 7820, 0 -2588, 0 8836, 0 3612, 0 1616, 0 -2205, 0 3164, 0 2444, 0 4104, 0 44002, 0 -42398, 0 50424, 0 -35976, 0 -11568, 0 -14028, 0 -15788, 0 -15408, 0 -15672, 0 -16044, 0 -16516, 0 -16612, 0 -15700, 0 -16444, 0 -15924, 0 -15652, 0 -16392, 0 -13840, 0 -21988, 0 -9244, 0 -25260, 0 -14309, 0 -11636, 0 -21168, 0 -13708, 0 -14560, 0 -17776, 0 -27889, 0 -13108, 0 -20824, 0 -16064, 0 -12560, 0 -21036, 0 -2
5460, 0 -20173, 0 -27964, 0 -13460, 0 -16547, 0 -4480, 0 -33460, 0 -28856, 0 -25196, 0 -19931, 0 -27232, 0 -16768, 0 -21408, 0 -29447, 0 -9240, 0 -14388, 0 -12416, 0 -14500, 0 -17072, 0 -21724, 0 -19160, 0 -13960, 0 -15264, 0 -19768, 0 -26632, 0 -20678, 0 -20790, 0 -20723, 0 -20947, 0 -20823, 0 -20416, 0 -21007, 0 -20785, 0 -18430, 0 54139, 0 -32261, 0 -20582, 0 -20364, 0 -16356, 0 -18492, 0 -18516, 0 -28378, 0 -8572, 0 -20708, 0 -14404, 0 -14660, 0 -24000, 0 -25540, 0 -21027, 0 -21508, 0 54822, 0 -31578, 0
 -23796, 0 -13480, 0 -15548, 0 -24076, 0 -13491, 0 -18570, 0 -17762, 0 -21184, 0 46702, 0 -39698, 0 -7780, 0 -24427, 0 -24312, 0 -24339, 0 -25060, 0 -19088, 0 -13240, 0 -26898, 0 -17360, 0 -14764, 0 -15336, 0 -15865, 0 -17020, 0 -22696, 0 -8376, 0 -25116, 0 -16272, 0 -13128, 0 -16966, 0 -16776, 0 -11188, 0 -5272, 0 53927, 0 -32473, 0 -12652, 0 -25880, 0 -20932, 0 -16508, 0 -21420, 0 -28084, 0 -19052, 0 -29548, 0 -32412, 0 -23316, 0 52865, 0 -33535, 0 18468, 0 8624, 0 42596, 0 12064, 0 13720, 0 14012, 0 1246
4, 0 10660, 0 11964, 0 24124, 0 20100, 0 8520, 0 17904, 0 27580, 0 27232, 0 27480, 0 19164, 0 8712, 0 21700, 0 30140, 0 13272, 0 16512, 0 8148, 0 8272, 0 8423, 0 25600, 0 27402, 0 21996, 0 25025, 0 25632, 0 33768, 0 8454, 0 16608, 0 38076, 0 16092, 0 20476, 0 32533, 0 21208, 0 22286, 0 24406, 0 26480, 0 27260, 0 36192, 0 28656, 0 -57360, 0 29040, 0 8008, 0 20928, 0 19900, 0 17610, 0 12324, 0 26240, 0 30180, 0 12368, 0 15712, 0 11212, 0 34248, 0 16073, 0 30472, 0 29143, 0 24925, 0 36892, 0 29160, 0 16631, 0
10751, 0 12344, 0 21516, 0 33539, 0 20391, 0 25652, 0 21020, 0 34374, 0 31651, 0 31138, 0 23087, 0 14553, 0 10680, 0 -6160, 0 -15558, 0 -3696, 0 -5644, 0 -1624, 0 -4056, 0 -5280, 0 -8768, 0 -13884, 0 33260, 0 36728, 0 33948, 0 34528, 0 31400, 0 30928, 0 35356, 0 35756, 0 38180, 0 34792, 0 27804, 0 36292, 0 1172, 0 364, 0 11532, 0 5692, 0 4920, 0 3208, 0 1050, 0 6264, 0 4580, 0 6920, 0 3020, 0 -1500, 0 -1284, 0 5989, 0 6952, 0 7324, 0 11928, 0 -75, 0 1476, 0 -884, 0 3484, 0 6616, 0 1772, 0 9017, 0 2580, 0 56
1, 0 3464, 0 5794, 0 2996, 0 12020, 0 11058, 0 8184, 0 5596, 0 4332, 0 5940, 0 4760, 0 11616, 0 5352, 0 3921, 0 6076, 0 5040, 0 8440, 0 2048, 0 17380, 0 25372, 0 23260, 0 13308, 0 17640, 0 13800, 0 13312, 0 45184, 0 -41216, 0 41944, 0 37336, 0 44028, 0 36428, 0 -26248, 0 40396, 0 -41060, 0 -41096, 0 42944, 0 43012, 0 -21504, 0 -32388, 0 38388, 0 -51660, 0 34740, 0 -37886, 0 -37760, 0 39116, 0 40160, 0 41088, 0 -33480, 0 40060, 0 -40780, 0 40312, 0 39948, 0 45432, 0 -40968, 0 32276, 0 -31220, 0 37972, 0 3532
0, 0 -38344, 0 -35896, 0 41524, 0 44360, 0 39988, 0 44120},
  {"MDT", 1 -21600, 0 -21600},
  {"CWT", 0 -18000, 1 -18000},
  {"NZST", 1 45000, 1 43200, 0 43200},
  {"CPT", 1 -18000},
  {"AWDT", 1 32400},
  {"IST", 0 10800, 0 7200, 0 19800, 1 2079, 0 0, 1 3600, 0 3600, 1 0},
  {"MEST", 1 7200},
  {"PMT", 0 561, 0 -13252, 0 -13236, 0 26240, 0 13505, 0 3464},
  {"AHDT", 1 -32400},
  {"WIB", 0 25200},
  {"NDDT", 1 -5400},
  {"BDT", 1 -36000},
  {"AMT", 0 -13840, 0 1172, 0 5692},
  {"CAST", 1 10800},
  {"EEMMTT", 0 7200},
  {"WEMT", 1 7200, 0 7200},
  {"TMT", 0 12344, 0 5940},
  {"IDDT", 1 14400},
  {"EMT", 0 -26248},
  {"AWST", 0 28800, 0 32400},
  {"TBMT", 0 10751},
  {"CEST", 1 7200, 0 7200, 1 10800},
  {"AHST", 0 -36000},
  {"NZMT", 0 41400},
  {"BST", 0 -39600, 1 -12756, 1 3600, 0 3600},
  {"YDT", 1 -28800},
  {"JDT", 1 36000},
  {"IMT", 0 25025, 0 7016},
  {"WAT", 0 3600, 1 3600},
  {"PLMT", 0 25590},
  {"AEDT", 1 39600, 0 39600},
  {"NDT", 1 -9052, 1 -9000, 0 -9000},
  {"MMT", 0 -2588, 0 -2670, 0 -20712, 0 -13491, 0 19172, 0 19270, 0 28656, 0 6600, 0 9017, 0 9079, 0 17640},
  {"SDMT", 0 -16800},
  {"YST", 0 -32400},
  {"CEMT", 0 10800, 1 10800},
  {"JST", 0 32400},
  {"PPMT", 0 -17340},
  {"QMT", 0 -18840},
  {"SAST", 0 5400, 0 7200, 1 10800},
  {"CDT", 1 -18000, 0 -18000, 1 -14400, 1 32400},
  {"BMT", 0 -14309, 0 -17776, 0 10656, 0 24124, 0 25632, 0 1050, 0 6264, 0 1786},
  {"WIT", 0 32400},
  {"AEST", 0 36000},
  {"NST", 0 -39600, 0 -12652, 0 -12600, 1 4772},
  {"YDDT", 1 -25200},
  {"FMT", 0 -4056},
  {"ChST", 0 36000},
  {"EAT", 0 10800},
  {"CST", 0 -21600, 0 -18000, 0 28800},
  {"KDT", 1 34200, 1 36000},
  {"JMT", 0 8440},
  {"PWT", 1 -25200},
  {"AWT", 1 -32400, 1 -10800, 0 -10800},
  {"PPT", 1 -25200},
  {"BDST", 1 7200},
  {"APT", 1 -32400, 1 -10800},
  {"GST", 0 36000},
  {"PMMT", 0 35312},
  {"EWT", 1 -14400, 0 -14400},
  {"EDDT", 1 -10800},
  {"EPT", 1 -14400},
  {"KST", 0 30600, 0 32400},
  {"RMT", 0 23087, 0 5794, 0 2996},
  {"CMT", 0 -15408, 0 -16060, 0 -16356, 0 -19176, 0 6900, 0 3020},
  {"HKT", 0 28800},
}
</small></pre></code>

sebres added on 2018-05-25 11:09:50: (text/x-fossil-wiki)
By working on the PoC for test-solution over all zones-coverage I found many another missing zones, e. g. for Anchorage:

<code><pre>
% set d [clock format [set c [clock add 10000000 6 months]] -timezone :America/Anchorage]
Mon Oct 26 07:46:40 AHST 1970
% expr {$c == [clock scan $d]}
1
% set d [clock format [set c [clock add 10000000 0 months]] -timezone :America/Anchorage]
Sun Apr 26 08:46:40 AHDT 1970
% expr {$c == [clock scan $d]}
unable to convert date-time string "Sun Apr 26 08:46:40 AHDT 1970": syntax error (characters 20-23)
</pre></code>
The reason is simply: the zone America/Anchorage has different shortcuts for different times: LMT, AST, AWT, APT, AHST, AHDT, AKST, AKDT

So the right solution would be to make an aliasing rules (map with legacy TZ -> real TZ), and some simply script that builds this map from library/tzdata/*.

As regards the ambiguity regarding ambiguous duplicates: for example it could get a time range to take it into account by searching of the proper real zone.

I'll do soon the back-porting of my tclclockmod to the tcl-core and later try to provide a ultimate solution round about legacy zones.

sebres added on 2018-05-23 16:24:00: (text/x-fossil-wiki)
Fixed for tclclockmod in <a href="https://github.com/tcltk/tclclockmod/commit/025c25a8bc915a843b708f69bf2857e32f367fb0">tcltk/tclclockmod - 025c25a8bc915a843b708f69bf2857e32f367fb0</a>

Fix for tcl-core will follow shortly.

BTW. I don't think that issue with ZP4-ZP6 zones can be easy fixed (because of the probable conflict with number like hour) and it should be fixed at all, because they are user zones...<br/>
Possibly better we should simply remove this zones.