Re: [racket-users] find-seconds daylight saving
On Thu, Nov 10, 2016 at 10:52 AM, Jon Zeppieri wrote: > > > On Thu, Nov 10, 2016 at 10:45 AM, Jon Zeppieri wrote: > >> >> >> On Thu, Nov 10, 2016 at 4:52 AM, George Neuner >> wrote: >> >>> >>> On 11/9/2016 2:18 AM, Ryan Culpepper wrote: >> >> >> >>> >>> Postgresql follows the ISO convention because the SQL standard follow >>> the ISO convention. Ask Postgresql for "+5" ... note I dropped the >>> separator and minutes (more below) ... and you will get back time in Mumbai >>> India. However, Postgresql has to interoperate with the opposing standard >>> TZ database, so if you ask for "EST" you will get the time for New York >>> City because Postgresql negated the offset. >>> >> >> I thought Postgres used the same convention as IANA, but it's been a >> while. >> >> > Ah, I see what's going on here. Right, so the tz database has certain time > zone names like: > > Etc/GMT-4 > > Where the *name itself* follows the POSIX convention, though it maps to an > offset that follows the ISO/Olson convention. You can see this if you look > at the source file "etcetera" in the tz database. You'll see lines like > this: > > ZoneEtc/GMT-14 14 - +14 > ZoneEtc/GMT-13 13 - +13 > ZoneEtc/GMT-12 12 - +12 > ZoneEtc/GMT-11 11 - +11 > > You can see that the time zone named Etc/GMT-14 maps to a single offset of > UTC+14. No joke. > > By the way, these time zones exist specifically *for* POSIX compatibility; that's why their names follow the POSIX convention. It's not that the tz database adopted the POSIX convention in general. Basically: don't use these time zones unless you have a very good reason to. Or ones like "EST." Stick to the ones that follow the continent_ish/city naming convention. - Jon -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] find-seconds daylight saving
On Thu, Nov 10, 2016 at 10:45 AM, Jon Zeppieri wrote: > > > On Thu, Nov 10, 2016 at 4:52 AM, George Neuner > wrote: > >> >> On 11/9/2016 2:18 AM, Ryan Culpepper wrote: > > > >> >> Postgresql follows the ISO convention because the SQL standard follow the >> ISO convention. Ask Postgresql for "+5" ... note I dropped the separator >> and minutes (more below) ... and you will get back time in Mumbai India. >> However, Postgresql has to interoperate with the opposing standard TZ >> database, so if you ask for "EST" you will get the time for New York City >> because Postgresql negated the offset. >> > > I thought Postgres used the same convention as IANA, but it's been a while. > > Ah, I see what's going on here. Right, so the tz database has certain time zone names like: Etc/GMT-4 Where the *name itself* follows the POSIX convention, though it maps to an offset that follows the ISO/Olson convention. You can see this if you look at the source file "etcetera" in the tz database. You'll see lines like this: ZoneEtc/GMT-14 14 - +14 ZoneEtc/GMT-13 13 - +13 ZoneEtc/GMT-12 12 - +12 ZoneEtc/GMT-11 11 - +11 You can see that the time zone named Etc/GMT-14 maps to a single offset of UTC+14. No joke. - Jon -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] find-seconds daylight saving
On Thu, Nov 10, 2016 at 4:52 AM, George Neuner wrote: > > On 11/9/2016 2:18 AM, Ryan Culpepper wrote: > >> >> Another option is to let PostgreSQL do it for you using AT TIME ZONE (or >> the timezone function): >> >> select ('2016-11-09 01:23:00Z'::timestamptz) >> at time zone 'us/eastern'; >> => 2016-11-08 20:23:00 >> >> But beware that PostgreSQL interprets numerical timezones backwards >> (sometimes?) (see https://www.postgresql.org/mes >> sage-id/20151021034109.3017@wrigleys.postgresql.org). I've read that >> thread and the docs and I still can't make sense of it. >> >> Ryan >> > > I know about this one. The problem is there are two TZ conventions which > use opposite arithmetic. > > - ISO-8601 labels east of Greenwich "+" and west "-" > - POSIX labels west of Greenwich "+" and east "-" > > The IANA TZ datebase follows POSIX convention. [Or maybe the reverse: I > think the database preceded POSIX] It's the reverse. > So if you query the TZ database for e.g., "EST", you get back "+05:00" as > the offset. > It's -05:00, but a quick word on the use of "EST," in particular: The string "EST" is used in two ways in the tz database; it's the name of a time zone that consistently has a UTC offset of -05:00, and it's also the symbolic name for the UTC offset of -05:00. These are different things. In the tz database, "time zone" doesn't mean the same thing as "UTC offset." A time zone is a collection of rules for determining what the UTC offset should be at a particular point in time in a particular region. For example, America/New_York is the canonical name of the time zone that's used on the Eastern seaboard of the United States. This time zone also has at least one synonym in the database (viz., US/Eastern). In this time zone, any point in time will occur at one of several UTC offsets. On my machine, using the system native zoneinfo database, I have the following UTC offsets that are used by America/New_York: (vector (tzoffset -14400 #t "EDT") (tzoffset -18000 #f "EST") (tzoffset -14400 #t "EWT") (tzoffset -14400 #t "EPT")) ("EWP" and "EPT," by the way, stand for "Eastern War Time" and "Eastern Peace Time," respectively.) (Note that the *time zone* called "EST" is not a synonym for America/New_York, because the former maps every point in time to UTC-05:00, whereas the latter does not.) Oh, and OS X (for... uh, reasons) uses the 32-bit version of the zoneinfo database. This is only capable of mapping 32-bit POSIX timestamps to UTC offsets. If you had the 64-bit version instead, there would be an additional offset in this timezone, namely "LMT." So, getting back to what I was saying: "EST" is both the name of a *time zone* that has only one UTC offset (which is also named "EST"), and it's also the name of a UTC offset. Now, the symbolic names of UTC offsets are not unique across the tz database. "EST" (when used as the name of an offset as opposed to the name of a time zone) is not guaranteed to correspond to -05:00 -- though I think, at the moment, it might. A better example is "CST." If you live in the US, you probably think, "Oh, that stands for "Central Standard Time," which is UTC-06:00." And it does, but it's also the name of an offset used in the Asia/Taipei time zone, where it corresponds to UTC+8:00. What's the point of all of this? If you use the Racket function `current-date` and you happen to live on the Eastern seaboard of the US, you might see in the time-zone-name field of the date* struct the string "EST." That is *not* the name of a time zone in the IANA sense; it's the name of a UTC offset. And since these names do not uniquely identify UTC offsets, they're only there as convenient, human-readable abbreviations. They are not useful for doing work. In summary: - Do not use the time-zone-name field of the date* struct for any computation. Use time-zone-offset instead. - If you need real time zones, in the IANA sense -- that is, if you don't already know the local UTC offset of some absolute point in time -- use Gregor. > > Postgresql follows the ISO convention because the SQL standard follow the > ISO convention. Ask Postgresql for "+5" ... note I dropped the separator > and minutes (more below) ... and you will get back time in Mumbai India. > However, Postgresql has to interoperate with the opposing standard TZ > database, so if you ask for "EST" you will get the time for New York City > because Postgresql negated the offset. > I thought Postgres used the same convention as IANA, but it's been a while. > > So far, so stupid. > > > But, SQL defines timezones as "numeric GMT offsets --- using the ISO sign > convention". Postgresql closely follows the standard very closely and the > developers interpret that word "numeric" very literally. So if you ask > for "-05:00" - Postgresql sees a string, assumes the user wants the POSIX > meaning, and negates the offset ... giving you Mumbai. > > > But what about fractional hours?ISO specifies TZs b
Re: [racket-users] find-seconds daylight saving
On 11/9/2016 2:18 AM, Ryan Culpepper wrote: Another option is to let PostgreSQL do it for you using AT TIME ZONE (or the timezone function): select ('2016-11-09 01:23:00Z'::timestamptz) at time zone 'us/eastern'; => 2016-11-08 20:23:00 But beware that PostgreSQL interprets numerical timezones backwards (sometimes?) (see https://www.postgresql.org/message-id/20151021034109.3017@wrigleys.postgresql.org). I've read that thread and the docs and I still can't make sense of it. Ryan I know about this one. The problem is there are two TZ conventions which use opposite arithmetic. - ISO-8601 labels east of Greenwich "+" and west "-" - POSIX labels west of Greenwich "+" and east "-" The IANA TZ datebase follows POSIX convention. [Or maybe the reverse: I think the database preceded POSIX] So if you query the TZ database for e.g., "EST", you get back "+05:00" as the offset. Postgresql follows the ISO convention because the SQL standard follow the ISO convention. Ask Postgresql for "+5" ... note I dropped the separator and minutes (more below) ... and you will get back time in Mumbai India. However, Postgresql has to interoperate with the opposing standard TZ database, so if you ask for "EST" you will get the time for New York City because Postgresql negated the offset. So far, so stupid. But, SQL defines timezones as "numeric GMT offsets --- using the ISO sign convention". Postgresql closely follows the standard very closely and the developers interpret that word "numeric" very literally. So if you ask for "-05:00" - Postgresql sees a string, assumes the user wants the POSIX meaning, and negates the offset ... giving you Mumbai. But what about fractional hours?ISO specifies TZs by (+|-)HHMM ... which looks like a number but is out of range for a TZ which must be -12..+12. POSIX, however, uses a separated string "(+|-)HH:MM", which doesn't look like a number. In Posegresql, SESSION TIME ZONE accepts TZ names, TZ abbreviations, POSIX offset strings, and DECIMAL offsets: e.g., -5.4, +2.71, etc. So if you want to specify NYC more closely than -5, you can say -5.4 and confuse people but be more accurate. AT TIME ZONE does not accept DECIMAL offsets - it wants only a TZ name, abbreviation, or POSIX offset string (with negated meaning). I hope this doesn't muddy the water further. I hate time zones. I hate time zones. I hate time zones. YMMV, George -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] find-seconds daylight saving
Hi Ryan, On 11/9/2016 2:18 AM, Ryan Culpepper wrote: Does the following do what you want? (require srfi/19) ;; date-at-tz : Date Integer -> Date ;; Returns date of equivalent instant in given timezone. (define (date-at-tz d tz) (let ([t (date->time-utc d)]) (time-utc->date t tz))) (define fmt "~Y-~m-~d ~H:~M:~S~z") (define s1 "2016-11-09 01:12:00Z") (define d1 (string->date s1 fmt)) (define d2 (date-at-tz d1 (* -5 60 60))) (date->string d1 fmt) ;; => "2016-11-09 01:23:00Z" (date->string d2 fmt) ;; => "2016-11-08 20:23:00-0500" (equal? (date->time-utc d1) (date->time-utc d2)) ;; => #t Yes this works, thank you! I think I goofed in starting down the road of add-duration ... which may have been a carry over from fighting with seconds->date. Another option is to let PostgreSQL do it for you using AT TIME ZONE (or the timezone function): select ('2016-11-09 01:23:00Z'::timestamptz) at time zone 'us/eastern'; => 2016-11-08 20:23:00 But beware that PostgreSQL interprets numerical timezones backwards (sometimes?) (see https://www.postgresql.org/message-id/20151021034109.3017@wrigleys.postgresql.org). I've read that thread and the docs and I still can't make sense of it. I can use Postgresql also - but only if I return the time as text. Returning it as a timestamptz gives me the right time, but in UTC. Either way it's inconvenient. As text, I have to convert it again to use it in a new query. As timestamptz the value is immediately usable, but not suited for viewing. 6 of one, 1/2 dozen of the other. But none of this solves the problem of timestamps that span daylight saving. No matter which TZ you pick, some of the conversions will be wrong. Obviously such a query can be split at the time change, but then you have to know when daylight saving starts and stops. Which means checking the TZ database. Sigh. George -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] find-seconds daylight saving
Thanks very much for tracking down the problem! I've pushed a repair. At Tue, 8 Nov 2016 17:31:53 -0500, Jon Zeppieri wrote: > I think Robby is right and the problem is here: > https://github.com/racket/racket/blob/4ce947da74d09abc9cda10a14e7407cda9386a44/ > racket/src/racket/src/fun.c#L9876 > > Well, that and the next line. There's only a `return 1;` for the case where > the given day-of-month is less than the DST change's day-of-month, but no > `return 0;` for the case where it's greater. All of the other comparisons > use the `dtxCOMP` macro, which handles both cases: > > ``` > # define dtxCOMP(f) if (a->f < b->f) return 1; if (a->f > b->f) return 0; > ``` > > Does that sound right? I don't have a Windows system at the moment, and I > can't reproduce on OS X. > > > - Jon > > > > > On Tue, Nov 8, 2016 at 2:29 PM, Robby Findler > wrote: > > > find-seconds returns a number, not a date? Maybe seconds->date is the > > culprit here? > > > > Robby > > > > On Tue, Nov 8, 2016 at 12:32 PM, George Neuner > > wrote: > > > > > > Racket 6.6 on Windows 7. > > > > > > find-seconds is getting the time zone wrong when local-time? is #t. > > > Somehow it is in daylight saving all through November. > > > > > > When local-time? is #f (UTC) the time zone and hour offset are > > > correct. [At least for "fall back", didn't check "spring ahead"] > > > > > > > > > > > > (for* [(m '(11 12)) > > >(d (in-range 1 31)) > > >#:unless [and (= m 12)(> d 5)] > > > ] > > > (println (seconds->date (find-seconds 0 0 0 d m 2016 #t > > > > > > => > > > (date* 0 0 0 1 11 2016 2 305 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 2 11 2016 3 306 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 3 11 2016 4 307 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 4 11 2016 5 308 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 5 11 2016 6 309 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 6 11 2016 0 310 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 7 11 2016 1 311 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 8 11 2016 2 312 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 9 11 2016 3 313 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 10 11 2016 4 314 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 11 11 2016 5 315 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 12 11 2016 6 316 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 13 11 2016 0 317 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 14 11 2016 1 318 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 15 11 2016 2 319 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 16 11 2016 3 320 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 17 11 2016 4 321 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 18 11 2016 5 322 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 19 11 2016 6 323 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 20 11 2016 0 324 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 21 11 2016 1 325 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 22 11 2016 2 326 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 23 11 2016 3 327 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 24 11 2016 4 328 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 25 11 2016 5 329 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 26 11 2016 6 330 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 27 11 2016 0 331 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 28 11 2016 1 332 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 29 11 2016 2 333 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 30 11 2016 3 334 #t -14400 0 "Eastern Daylight Time") > > > (date* 0 0 0 1 12 2016 4 335 #f -18000 0 "Eastern Standard Time") > > > (date* 0 0 0 2 12 2016 5 336 #f -18000 0 "Eastern Standard Time") > > > (date* 0 0 0 3 12 2016 6 337 #f -18000 0 "Eastern Standard Time") > > > (date* 0 0 0 4 12 2016 0 338 #f -18000 0 "Eastern Standard Time") > > > (date* 0 0 0 5 12 2016 1 339 #f -18000 0 "Eastern Standard Time") > > > > > > > > > George > > > > > > -- > > > You received this message because you are subscribed to the Google > > Groups "Racket Users" group. > > > To unsubscribe from this group and stop receiving emails from it, send > > an email to racket-users+unsubscr...@googlegroups.com. > > > For more options, visit https://groups.google.com/d/optout. > > > > -- > > You received this message because you are subscribed to the Google Groups > > "Racket Users" group. > > To unsubscribe from this group and stop receiving emails from it, send an > > email to racket-users+unsubscr...@googlegroups.com. > > For more options, visit https://groups.google.com/d/optout. > > > > -- > You received this message because you are subscribed to the Google Groups > "Racket Users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to racket-users+uns
Re: [racket-users] find-seconds daylight saving
On Tue, Nov 8, 2016 at 11:24 PM, George Neuner wrote: > Hi Jon, > > On 11/8/2016 6:28 PM, Jon Zeppieri wrote: > > > George, these are not correct results. The UTC offset is correct, but the >> time fields are not -- under the assumption that you're trying to >> round-trip them unchanged. (But maybe that's not a correct assumption.) At >> any rate, I think your original example demonstrates a problem with >> seconds->date on Windows. >> > > Sorry, that was confusing. What I meant to say was: the results are > correct (given the treatment of the original date fields as UTC and the > treatment of the resulting seconds as local), but based on your original > post, I don't think they're the results you were after. But I'm not certain > of that. > > - Jon > > > What I'm trying to do is the following: > > - I'm given 2 datetimes as iso8601 -MM-DD HH:MM strings, and a time > zone offset > - create UTC datetimes from the strings and tz > - query a database returning records between the 2 UTC datetimes > > OK that was pretty easy. I believe I need to get [or look up somehow] a > separate tz for each date string because the range may span both standard > and daylight time, but at least I can get this far. > > Now the hard part: > > - I need to turn the UTC datetimes on all the results back into local > times with the right time zone > > This part is driving me nuts. Nothing seems to work exactly right. > (seconds->date ... #T) seems to get the numbers right, but not always the > timezone, > Yeah, and this is because you're running into an actual bug that only affects Windows. I think it's a very simple matter to fix, but since it only affects Windows, and I don't have a Windows machine, I can't verify that. > and in any case it is limited to the local timezone of the machine - > useless if local *is* UTC, and since I can't specify an arbitrary timezone, > I can't use it in a server side application. > Right -- and this is something that Gregor can help with. If you have UTC datetimes, you can first translate these from date* instances to Gregor moments, using 0 as the time zone offset. Then, you can use `adjust-timezone` to give you a new moment instance that represents the same point in time but with whatever offset you specify. That probably sounds a bit overly complicated. The db library doesn't directly support Gregor, which is why you would need to translate from one representation to another: ``` (require racket/date racket/match gregor) (define (date*->moment/offset d offset) (match d [(date* sec min hr day mon yr _ _ _ off ns _) (adjust-timezone (moment yr mon day hr min sec ns #:tz off) offset)])) ;; ex: (date*->moment/offset (current-date) -18000) ``` This (or Ryan's approach, which uses SRFI 19 instead of Gregor) will work fine if you only need UTC offsets. If, however, you need to work with proper time zones (like America/New_York) -- which you will if you need to do any date arithmetic on localized dates -- then you'll want to stick with Gregor. About the Gregor documentation, it would be great if you could drop me a note with suggestions for improving it. - Jon -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] find-seconds daylight saving
On 11/08/2016 11:24 PM, George Neuner wrote: [...] - I need to turn the UTC datetimes on all the results back into local times with the right time zone Does the following do what you want? (require srfi/19) ;; date-at-tz : Date Integer -> Date ;; Returns date of equivalent instant in given timezone. (define (date-at-tz d tz) (let ([t (date->time-utc d)]) (time-utc->date t tz))) (define fmt "~Y-~m-~d ~H:~M:~S~z") (define s1 "2016-11-09 01:12:00Z") (define d1 (string->date s1 fmt)) (define d2 (date-at-tz d1 (* -5 60 60))) (date->string d1 fmt) ;; => "2016-11-09 01:23:00Z" (date->string d2 fmt) ;; => "2016-11-08 20:23:00-0500" (equal? (date->time-utc d1) (date->time-utc d2)) ;; => #t Another option is to let PostgreSQL do it for you using AT TIME ZONE (or the timezone function): select ('2016-11-09 01:23:00Z'::timestamptz) at time zone 'us/eastern'; => 2016-11-08 20:23:00 But beware that PostgreSQL interprets numerical timezones backwards (sometimes?) (see https://www.postgresql.org/message-id/20151021034109.3017@wrigleys.postgresql.org). I've read that thread and the docs and I still can't make sense of it. Ryan -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] find-seconds daylight saving
Hi Jon, On 11/8/2016 6:28 PM, Jon Zeppieri wrote: George, these are not correct results. The UTC offset is correct, but the time fields are not -- under the assumption that you're trying to round-trip them unchanged. (But maybe that's not a correct assumption.) At any rate, I think your original example demonstrates a problem with seconds->date on Windows. Sorry, that was confusing. What I meant to say was: the results are correct (given the treatment of the original date fields as UTC and the treatment of the resulting seconds as local), but based on your original post, I don't think they're the results you were after. But I'm not certain of that. - Jon What I'm trying to do is the following: - I'm given 2 datetimes as iso8601 -MM-DD HH:MM strings, and a time zone offset - create UTC datetimes from the strings and tz - query a database returning records between the 2 UTC datetimes OK that was pretty easy. I believe I need to get [or look up somehow] a separate tz for each date string because the range may span both standard and daylight time, but at least I can get this far. Now the hard part: - I need to turn the UTC datetimes on all the results back into local times with the right time zone This part is driving me nuts. Nothing seems to work exactly right. (seconds->date ... #T) seems to get the numbers right, but not always the timezone, and in any case it is limited to the local timezone of the machine - useless if local *is* UTC, and since I can't specify an arbitrary timezone, I can't use it in a server side application. What I have tried so far amounts to: [reformatted a bit] (let* [ (tz -4) (offset (* 60 60 tz)) (d (make-time 'time-duration 0 offset)) (date-in (sql-datetime->srfi-date ... ));; date comes in here (t1(date->time-utc date-in)) (t2(add-duration t1 d)) (date1-lcl (time-utc->date t2 offset)) (date1-utc (time-utc->date t2 0 )) (t3(date->seconds date-in)) (t4(+ t3 offset)) (date2-lcl (seconds->date t4 #t)) (date2-utc (seconds->date t4 #f)) (date3-lcl (date* (date-second date-in) (date-minute date-in) (date-hour date-in) (date-daydate-in) (date-month date-in) (date-year date-in) 0 0 #f offset 0 "LCL" )) (date3-utc (date* (date-second date-in) (date-minute date-in) (date-hour date-in) (date-daydate-in) (date-month date-in) (date-year date-in) 0 0 #f 0 0 "UTC" )) ] (printf "UTC input : ~s ~s~n" date-in (date->string date-in "~1 ~2")) (printf "~n") (printf "srfi tz : ~s ~s~n" date1-lcl (date->string date1-lcl "~1 ~2")) (printf "srfi 0: ~s ~s~n" date1-utc (date->string date1-utc "~1 ~2")) (printf "~n") (printf "s->d #t : ~s ~s~n" date2-lcl (date->string date2-lcl "~1 ~2")) (printf "s->d #f : ~s ~s~n" date2-utc (date->string date2-utc "~1 ~2")) (printf "~n") (printf "date* ofst: ~s ~s~n" date3-lcl (date->string date3-lcl "~1 ~2")) (printf "date* 0 : ~s ~s~n" date3-utc (date->string date3-utc "~1 ~2")) ) => UTC input : #(struct:date* 0 0 4 12 11 2016 6 316 #f 0 0 "") "2016-11-12 04:00:00Z" srfi tz : #(struct:date* 0 0 20 11 11 2016 5 315 #f -14400 0 "") "2016-11-11 20:00:00-0400" srfi 0: #(struct:date* 0 0 0 12 11 2016 6 316 #f 0 0 "") "2016-11-12 00:00:00Z" s->d #t : #(struct:date* 0 0 0 12 11 2016 6 316 #t -14400 0 "Eastern Daylight Time") "2016-11-12 00:00:00-0400" s->d #f : #(struct:date* 0 0 5 12 11 2016 6 316 #f 0 0 "UTC")"2016-11-12 05:00:00Z" date* ofst: #(struct:date* 0 0 4 12 11 2016 0 0 #f -14400 0 "LCL") "2016-11-12 04:00:00-0400" date* 0 : #(struct:date* 0 0 4 12 11 2016 0 0 #f 0 0 "UTC") "2016-11-12 04:00:00Z" I've been thinking I should look into Gregor, but a brief skimming of its docs was daunting. George -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.googl
Re: [racket-users] find-seconds daylight saving
On Tue, Nov 8, 2016 at 6:26 PM, Jon Zeppieri wrote: > > > On Tue, Nov 8, 2016 at 6:18 PM, George Neuner > wrote: > >> >> On 11/8/2016 2:29 PM, Robby Findler wrote: >> >>> find-seconds returns a number, not a date? Maybe seconds->date is the >>> culprit here? >>> >>> Robby >>> >> >> Spoke too soon. 1 combination gets it right: (seconds->date >> (find-seconds ... #F) #T). >> >> Note that (for me) Nov 6 should be DST [until 2AM], but Nov 7 should be >> EST. >> >> -- >> (require racket/date) >> >> (seconds->date (find-seconds 0 0 0 6 11 2016 #f) #f) >> (seconds->date (find-seconds 0 0 0 6 11 2016 #f) #t) >> (seconds->date (find-seconds 0 0 0 6 11 2016 #t) #f) >> (seconds->date (find-seconds 0 0 0 6 11 2016 #t) #t) >> (displayln "") >> (seconds->date (find-seconds 0 0 0 7 11 2016 #f) #f) >> (seconds->date (find-seconds 0 0 0 7 11 2016 #f) #t) >> (seconds->date (find-seconds 0 0 0 7 11 2016 #t) #f) >> (seconds->date (find-seconds 0 0 0 7 11 2016 #t) #t) >> >> => >> date* 0 0 0 6 11 2016 0 310 #f 0 0 "UTC") >> (date* 0 0 20 5 11 2016 6 309 #t -14400 0 "Eastern Daylight Time") >> (date* 0 0 4 6 11 2016 0 310 #f 0 0 "UTC") >> (date* 0 0 0 6 11 2016 0 310 #t -14400 0 "Eastern Daylight Time") >> >> (date* 0 0 0 7 11 2016 1 311 #f 0 0 "UTC") >> (date* 0 0 19 6 11 2016 0 310 #f -18000 0 "Eastern Standard Time") >> (date* 0 0 5 7 11 2016 1 311 #f 0 0 "UTC") >> (date* 0 0 0 7 11 2016 1 311 #t -14400 0 "Eastern Daylight Time") >> -- >> >> > > George, these are not correct results. The UTC offset is correct, but the > time fields are not -- under the assumption that you're trying to > round-trip them unchanged. (But maybe that's not a correct assumption.) At > any rate, I think your original example demonstrates a problem with > seconds->date on Windows. > > > Sorry, that was confusing. What I meant to say was: the results are correct (given the treatment of the original date fields as UTC and the treatment of the resulting seconds as local), but based on your original post, I don't think they're the results you were after. But I'm not certain of that. - Jon -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] find-seconds daylight saving
On Tue, Nov 8, 2016 at 6:18 PM, George Neuner wrote: > > On 11/8/2016 2:29 PM, Robby Findler wrote: > >> find-seconds returns a number, not a date? Maybe seconds->date is the >> culprit here? >> >> Robby >> > > Spoke too soon. 1 combination gets it right: (seconds->date > (find-seconds ... #F) #T). > > Note that (for me) Nov 6 should be DST [until 2AM], but Nov 7 should be > EST. > > -- > (require racket/date) > > (seconds->date (find-seconds 0 0 0 6 11 2016 #f) #f) > (seconds->date (find-seconds 0 0 0 6 11 2016 #f) #t) > (seconds->date (find-seconds 0 0 0 6 11 2016 #t) #f) > (seconds->date (find-seconds 0 0 0 6 11 2016 #t) #t) > (displayln "") > (seconds->date (find-seconds 0 0 0 7 11 2016 #f) #f) > (seconds->date (find-seconds 0 0 0 7 11 2016 #f) #t) > (seconds->date (find-seconds 0 0 0 7 11 2016 #t) #f) > (seconds->date (find-seconds 0 0 0 7 11 2016 #t) #t) > > => > date* 0 0 0 6 11 2016 0 310 #f 0 0 "UTC") > (date* 0 0 20 5 11 2016 6 309 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 4 6 11 2016 0 310 #f 0 0 "UTC") > (date* 0 0 0 6 11 2016 0 310 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 7 11 2016 1 311 #f 0 0 "UTC") > (date* 0 0 19 6 11 2016 0 310 #f -18000 0 "Eastern Standard Time") > (date* 0 0 5 7 11 2016 1 311 #f 0 0 "UTC") > (date* 0 0 0 7 11 2016 1 311 #t -14400 0 "Eastern Daylight Time") > -- > > George, these are not correct results. The UTC offset is correct, but the time fields are not -- under the assumption that you're trying to round-trip them unchanged. (But maybe that's not a correct assumption.) At any rate, I think your original example demonstrates a problem with seconds->date on Windows. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] find-seconds daylight saving
On 11/8/2016 2:29 PM, Robby Findler wrote: find-seconds returns a number, not a date? Maybe seconds->date is the culprit here? Robby Spoke too soon. 1 combination gets it right: (seconds->date (find-seconds ... #F) #T). Note that (for me) Nov 6 should be DST [until 2AM], but Nov 7 should be EST. -- (require racket/date) (seconds->date (find-seconds 0 0 0 6 11 2016 #f) #f) (seconds->date (find-seconds 0 0 0 6 11 2016 #f) #t) (seconds->date (find-seconds 0 0 0 6 11 2016 #t) #f) (seconds->date (find-seconds 0 0 0 6 11 2016 #t) #t) (displayln "") (seconds->date (find-seconds 0 0 0 7 11 2016 #f) #f) (seconds->date (find-seconds 0 0 0 7 11 2016 #f) #t) (seconds->date (find-seconds 0 0 0 7 11 2016 #t) #f) (seconds->date (find-seconds 0 0 0 7 11 2016 #t) #t) => date* 0 0 0 6 11 2016 0 310 #f 0 0 "UTC") (date* 0 0 20 5 11 2016 6 309 #t -14400 0 "Eastern Daylight Time") (date* 0 0 4 6 11 2016 0 310 #f 0 0 "UTC") (date* 0 0 0 6 11 2016 0 310 #t -14400 0 "Eastern Daylight Time") (date* 0 0 0 7 11 2016 1 311 #f 0 0 "UTC") (date* 0 0 19 6 11 2016 0 310 #f -18000 0 "Eastern Standard Time") (date* 0 0 5 7 11 2016 1 311 #f 0 0 "UTC") (date* 0 0 0 7 11 2016 1 311 #t -14400 0 "Eastern Daylight Time") -- George -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] find-seconds daylight saving
On 11/8/2016 2:29 PM, Robby Findler wrote: find-seconds returns a number, not a date? Maybe seconds->date is the culprit here? Robby Possibly. But both functions take an optional local-time? parameter. The various combinations don't seem to affect the time zone wrt daylight saving. George -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] find-seconds daylight saving
I think Robby is right and the problem is here: https://github.com/racket/racket/blob/4ce947da74d09abc9cda10a14e7407cda9386a44/racket/src/racket/src/fun.c#L9876 Well, that and the next line. There's only a `return 1;` for the case where the given day-of-month is less than the DST change's day-of-month, but no `return 0;` for the case where it's greater. All of the other comparisons use the `dtxCOMP` macro, which handles both cases: ``` # define dtxCOMP(f) if (a->f < b->f) return 1; if (a->f > b->f) return 0; ``` Does that sound right? I don't have a Windows system at the moment, and I can't reproduce on OS X. - Jon On Tue, Nov 8, 2016 at 2:29 PM, Robby Findler wrote: > find-seconds returns a number, not a date? Maybe seconds->date is the > culprit here? > > Robby > > On Tue, Nov 8, 2016 at 12:32 PM, George Neuner > wrote: > > > > Racket 6.6 on Windows 7. > > > > find-seconds is getting the time zone wrong when local-time? is #t. > > Somehow it is in daylight saving all through November. > > > > When local-time? is #f (UTC) the time zone and hour offset are > > correct. [At least for "fall back", didn't check "spring ahead"] > > > > > > > > (for* [(m '(11 12)) > >(d (in-range 1 31)) > >#:unless [and (= m 12)(> d 5)] > > ] > > (println (seconds->date (find-seconds 0 0 0 d m 2016 #t > > > > => > > (date* 0 0 0 1 11 2016 2 305 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 2 11 2016 3 306 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 3 11 2016 4 307 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 4 11 2016 5 308 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 5 11 2016 6 309 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 6 11 2016 0 310 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 7 11 2016 1 311 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 8 11 2016 2 312 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 9 11 2016 3 313 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 10 11 2016 4 314 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 11 11 2016 5 315 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 12 11 2016 6 316 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 13 11 2016 0 317 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 14 11 2016 1 318 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 15 11 2016 2 319 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 16 11 2016 3 320 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 17 11 2016 4 321 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 18 11 2016 5 322 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 19 11 2016 6 323 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 20 11 2016 0 324 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 21 11 2016 1 325 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 22 11 2016 2 326 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 23 11 2016 3 327 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 24 11 2016 4 328 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 25 11 2016 5 329 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 26 11 2016 6 330 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 27 11 2016 0 331 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 28 11 2016 1 332 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 29 11 2016 2 333 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 30 11 2016 3 334 #t -14400 0 "Eastern Daylight Time") > > (date* 0 0 0 1 12 2016 4 335 #f -18000 0 "Eastern Standard Time") > > (date* 0 0 0 2 12 2016 5 336 #f -18000 0 "Eastern Standard Time") > > (date* 0 0 0 3 12 2016 6 337 #f -18000 0 "Eastern Standard Time") > > (date* 0 0 0 4 12 2016 0 338 #f -18000 0 "Eastern Standard Time") > > (date* 0 0 0 5 12 2016 1 339 #f -18000 0 "Eastern Standard Time") > > > > > > George > > > > -- > > You received this message because you are subscribed to the Google > Groups "Racket Users" group. > > To unsubscribe from this group and stop receiving emails from it, send > an email to racket-users+unsubscr...@googlegroups.com. > > For more options, visit https://groups.google.com/d/optout. > > -- > You received this message because you are subscribed to the Google Groups > "Racket Users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to racket-users+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [racket-users] find-seconds daylight saving
find-seconds returns a number, not a date? Maybe seconds->date is the culprit here? Robby On Tue, Nov 8, 2016 at 12:32 PM, George Neuner wrote: > > Racket 6.6 on Windows 7. > > find-seconds is getting the time zone wrong when local-time? is #t. > Somehow it is in daylight saving all through November. > > When local-time? is #f (UTC) the time zone and hour offset are > correct. [At least for "fall back", didn't check "spring ahead"] > > > > (for* [(m '(11 12)) >(d (in-range 1 31)) >#:unless [and (= m 12)(> d 5)] > ] > (println (seconds->date (find-seconds 0 0 0 d m 2016 #t > > => > (date* 0 0 0 1 11 2016 2 305 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 2 11 2016 3 306 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 3 11 2016 4 307 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 4 11 2016 5 308 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 5 11 2016 6 309 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 6 11 2016 0 310 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 7 11 2016 1 311 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 8 11 2016 2 312 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 9 11 2016 3 313 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 10 11 2016 4 314 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 11 11 2016 5 315 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 12 11 2016 6 316 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 13 11 2016 0 317 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 14 11 2016 1 318 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 15 11 2016 2 319 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 16 11 2016 3 320 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 17 11 2016 4 321 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 18 11 2016 5 322 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 19 11 2016 6 323 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 20 11 2016 0 324 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 21 11 2016 1 325 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 22 11 2016 2 326 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 23 11 2016 3 327 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 24 11 2016 4 328 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 25 11 2016 5 329 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 26 11 2016 6 330 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 27 11 2016 0 331 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 28 11 2016 1 332 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 29 11 2016 2 333 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 30 11 2016 3 334 #t -14400 0 "Eastern Daylight Time") > (date* 0 0 0 1 12 2016 4 335 #f -18000 0 "Eastern Standard Time") > (date* 0 0 0 2 12 2016 5 336 #f -18000 0 "Eastern Standard Time") > (date* 0 0 0 3 12 2016 6 337 #f -18000 0 "Eastern Standard Time") > (date* 0 0 0 4 12 2016 0 338 #f -18000 0 "Eastern Standard Time") > (date* 0 0 0 5 12 2016 1 339 #f -18000 0 "Eastern Standard Time") > > > George > > -- > You received this message because you are subscribed to the Google Groups > "Racket Users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to racket-users+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.