Hey DM,
Need some clarification - I've noticed an unexpected date when saving a message (when called from CLI jsexec - havent checked when the terminal server calling the script).
I'm calling save_msg(), using a header with a date that has:
RFC-822 format (as per the https://synchro.net/docs/jsobjs.html), and that results in a message time of:
date = strftime("%a, %d %b %Y %I:%M:%S %z",time());
// Tue, 17 Dec 2024 02:32:19 +1100
(I know time() is implied with strftime()).
when_written 67604803 0294 Tue Dec 17 02:32:19 2024 UTC+11:00 when_imported 6760F0C3 0000 Tue Dec 17 14:32:19 2024 UTC
I also know time() is returning the correct epoch time (I've compared it with https://www.epochconverter.com/)
a) Shouldnt the strftime() call return "14:32:19 +1100" - which would fix the when_written value. (The message renders with a "written 12hrs ago" statement).
b) Shouldnt the when_imported by "02:32:19 UTC" (if it is recording timestamps in UTC, or 14:32:19 UTC+1100 if rendering local time)?
c) AU is GMT+11 right now (summer time, normally GMT+10), so system time is 14:32 - not sure when strftime is returning 02:32 (12 hrs earlier)
Incidently, I used %Z in the strftime() call (instead of %z), which results in AEDT (right now) - and it resulted in a when_written of:
when_written 3A24FDD0 0000 Thu Nov 30 00:00:00 2000 UTC
date = strftime("%a, %d %b %Y %I:%M:%S %Z");
// Tue, 17 Dec 2024 02:28:01 AEDT
I guess save_msg() date parsing doesnt understand AEDT?
date = strftime("%a, %d %b %Y %I:%M:%S %z",time());
// Tue, 17 Dec 2024 02:32:19 +1100
MsgBase.save_msg() will using the current date/time and time zone when saving a message. You have a reason to not do this?
You shouldn't use the 'date' property unless you have to. Either use the default (current date/time and zone) are set the when_written_time and when_written_zone header fields instead.
date = strftime("%a, %d %b %Y %I:%M:%S %z",time());
// Tue, 17 Dec 2024 02:32:19 +1100
a) Shouldnt the strftime() call return "14:32:19 +1100" - which would fix the when_written value. (The message renders with a "written 12hrs ago" statement).
date = strftime("%a, %d %b %Y %I:%M:%S %z",time());
// Tue, 17 Dec 2024 02:32:19 +1100
MsgBase.save_msg() will using the current date/time and time zone when saving a message. You have a reason to not do this?
Yes - I'm setting the time of some messages to the same time of a file (obtained by new File().date - which also is returning a time_t)
You shouldn't use the 'date' property unless you have to. Either use the default (current date/time and zone) are set the when_written_time and when_written_zone header fields instead.
OK, I'll try. What is a valid use case of using the "date" property - I'm curious since it is a valid argument?
date = strftime("%a, %d %b %Y %I:%M:%S %z",time());
// Tue, 17 Dec 2024 02:32:19 +1100
a) Shouldnt the strftime() call return "14:32:19 +1100" - which would fix the when_written value. (The message renders with a "written 12hrs ago" statement).
I'm still wondering why strftime() is still returning an invalid time - out by the timezone plus 1 hr?
The JS strftime() function is just a wrapper for the C run-time library function of the same name. So depending on your OS, you can either run "man strftime" or see https://learn.microsoft.com/en-us/cpp/c-runtime-library/refere nce/strftime-wcsftime-strftime-l-wcsftime-l to read more up on how strftime() works for your platform.
root@ansitex-dev:/opt/sbbs/mods/ansitex# date
Wed Dec 18 12:08:51 AEDT 2024
OK, I'm convinced there is something messed up with time recording. So I'll start with one piece at a time.
I'm storing messages with save_msg(), and I am *not* setting date, when_imported* or when_written*.
According to the OS, the time is:
root@ansitex-dev:/opt/sbbs/mods/ansitex# date
Wed Dec 18 12:08:51 AEDT 2024
The message saved is record with this:
when_written 6762209C 0000 Wed Dec 18 12:08:44 2024 UTC
when_imported 6762209C 0000 Wed Dec 18 12:08:44 2024 UTC
This is not correct.
Why isnt timezone information being used when storing the current time? (It would seem apparent that Sync knows the time zone to display the statement "hrs from now")
What do you have set in SCFG->System->Local Time Zone? This is the default time zone information used by MsgBase.save_msg() and stored in the message header (if not otherwise specified in the message header object).
It should be storing whatever you have configured in SCFG->System->Local Time Zone.
dateWed Dec 18 15:26:39 AEDT 2024
jsexec ansitex/tools/test-strftime.jsWed, 18 Dec 2024 03:27:19 +1100
php tools/test-strftime.phpWed, 18 Dec 2024 03:27:19 +1100
Re: JS Object save_msg()
By: Digital Man to deon on Tue Dec 17 2024 05:36 pm
Howdy,
What do you have set in SCFG->System->Local Time Zone? This is the default time zone information used by MsgBase.save_msg() and stored in the message header (if not otherwise specified in the message header object).
It should be storing whatever you have configured in SCFG->System->Local Time Zone.
OK, it is UTC in there.
So this just is confusing, and IMHO messed up. I must have the wrong impression of Syncs timezone handling.
If you dont supply a datetime stamp (via any of the header save attributes that have a date/time), and Sync "figures it out" why cant it figure out the timezone of that time it gets as well?
Sync obviously knows the time zone - given that it displayed that message, that it saved 3s earlier with a "UTC" timezone as "11 hrs from now". Its not using that System->Local->Time Zone when displaying the message?
I think it can be improved, but if I'm wrong, I'd like to understand why my thinking is wrong...
Oh, and there *is* a problem with strftime(), but it may not be SBBS related.
2-3 hrs ago, my test script:
writeln(strftime("%a, %d %b %Y %I:%M:%S %z",time()));
was returning a correct date/time and timezone information - had me baffled, especially after I posted yesterday.
OK, it is UTC in there.
Is that intentional?
Synchronet doesn't figure it out, it just uses the timezone you have configured in SCFG->System.
timezone don't agree, the Terminal Server logs a warning during startup: "Configured time zone (x, 0xYYYY, offset: z) does not match system-local time zone offset: n"
Are you getting this warning log message?
You have a mismatch in your configuration. If that's unintentional, then I guess I could make that warning log message an error instead, to hopefully insure that sysops are aware of it in the future. If it's intentional, then I guess I would want to know why and then figure out how to support such a configuration with fewer surprises.
Are you messing with your system's timezone configuration or TZ environment variable?
Re: JS Object save_msg()
By: Digital Man to deon on Tue Dec 17 2024 09:19 pm
Howdy,
OK, it is UTC in there.
Is that intentional?
No. This is a vanilla, mostly unconfigured, install of Sync (running on my laptop that I use to build my ansitex shell).
Synchronet doesn't figure it out, it just uses the timezone you have configured in SCFG->System.
It figures out the "current time" (from the OS?) to store in the when_imported_time and when_written_time fields though right? I would have thought it would be easy to get the timezone from the OS, to populate the *_zone fields?
timezone don't agree, the Terminal Server logs a warning during startup: "Configured time zone (x, 0xYYYY, offset: z) does not match system-local time zone offset: n"
Are you getting this warning log message?
Dont know, hadnt looked. With the other stuff the gets spawed out when starting sync, it doesnt stand out. (I just restarted, and yes its there, but it doesnt look like a "warning" against all the other informational messages.)
You have a mismatch in your configuration. If that's unintentional, then I guess I could make that warning log message an error instead, to hopefully insure that sysops are aware of it in the future. If it's intentional, then I guess I would want to know why and then figure out how to support such a configuration with fewer surprises.
Can you always get the timezone from the OS?
Why have a configured timezone at all?
If I want to display everything in a timezone, then sure, that makes
sense (eg: my host is in a VM in country "X", but I am in country "Y"), but to work out and manipulate dates/times I would have thought you could do that all based on what the OS returns?
Are you messing with your system's timezone configuration or TZ environment variable?
No. Cant imagine a timezone configuration or TZ variable that would still return +11:00/AEDT but be 12 hrs ago (hence why I used the OS's date command in the example output to show what the OS's time was).
Can you always get the timezone from the OS?
Could, yes, but prefer to give the sysop the option to be more specific.
Why have a configured timezone at all?
Explained above.
Your message came here as posted on:
"Wed Dec 18 2024 05:14 pm AEDT (30 minutes ago)"
If we only used "what the OS returns", your message would have been posted on: "Wed Dec 18 2024 05:14 pm +11:00 (30 minutes ago)"
Why have a configured timezone at all?
Explained above.
OK, fair enough. I guess I dont understand why a sysop would configure their OS timezone different to their BBS timezone.
If they didnt have access to the OS configuration, then fair enough, but I would have thought that was a pretty rare/remote case - and in that case setting that scfg...Local Time Zone setting could be used to display the times in that timezone they wanted.
Your message came here as posted on:
"Wed Dec 18 2024 05:14 pm AEDT (30 minutes ago)"
If we only used "what the OS returns", your message would have been posted on: "Wed Dec 18 2024 05:14 pm +11:00 (30 minutes ago)"
Personally, I prefer the later. Its pretty absolute, where some folks may not know what AEDT/ACST/ACDT are.
Anyway, while the OS might just give you the timezone UTC offset, a quick parse of /etc/localtime (on linux and mac at least) would give you the timezone string as well. Dont know if that is at all possible on Win.
Personally I think that's better than a scenario where the time or time_t value is forced to a timezone that makes the usage of that value untrue. <shrug>
They shouldn't normally: hence the warning upon startup. But some sysops may legitimately want to display local times in UTC (big with HAM operators) and maybe have some good reason why their system/OS is not configured for UTC as well.
You're suggesting that SCFG display the current date/time (and zone string) in each timezone that's choosable? That'd be doable, if that's what you're suggesting.
Nothing's impossible. We could do more to work around a sysop that doesn't use the config wizard and ignores warnings. <shrug> But I don't see how that'd help your situation now.
time_t values are always in UTC (they're not impacted by any timezone
Re: JS Object save_msg()
By: Digital Man to deon on Wed Dec 18 2024 09:35 am
Howdy,
They shouldn't normally: hence the warning upon startup. But some sysops may legitimately want to display local times in UTC (big with HAM operators) and maybe have some good reason why their system/OS is not configured for UTC as well.
OK, great, that's what I am suggesting to. Using scfg -> ... -> Local Time Zone, to *display* times in a format of my choosing, regardless of the underlying OS setting.
Nothing's impossible. We could do more to work around a sysop that doesn't use the config wizard and ignores warnings. <shrug> But I don't see how that'd help your situation now.
For me I dont think it needs to a workaround. I would expect SBBS has access to all the system calls to handle mail internally as UTC (as it does), and configuration is used to display it in a timezone of their choosing.
time_t values are always in UTC (they're not impacted by any timezone
I know.
The problem I am having is this:
I used save_msg() to post a message, without supplying values to date (and when I did that didnt work as expected either), nor values to the when_* values.
The system time at the time I called save_msg() was
Wed Dec 18 12:32:06 2024 AEDT (or +1100) (which is time_t 1734485526)
Sync recorded that message as
Wed Dec 18 12:32:06 2024 UTC (which is time_t 1734525126)
And thus, when I promptly read the message, it was "11 hrs from now".
This is just wrong. And you told me it chose "UTC" because of that setting (scfg -> ... -> Local Time Zone).
My point is, scfg -> ... -> Local Time Zone shouldnt be used to evaluate what time values sync uses to store time_t ints,
it should be used to
display the time_t int in a time zone of my choosing.
I dont believe there is any sysop who would configure their OS to UTC+1100, and purposely configure their BBS to forcefully determine the OS time as UTC (or anything else for that matter). (Which is what that setting is doing in this instance).
That was probably valid in the DOS days, when DOS didnt know timezones, but these days, it works against you.
Now that you've fixed your configuration, you're good, yeah?
Now that you've fixed your configuration, you're good, yeah?
Yes but...
Consider these two messages:
a) scfg -> System -> Local Time Zone = +11:00
index record 152
when_written 6763D130 0294 Thu Dec 19 18:54:24 2024 UTC+11:00 when_imported 6763D130 0294 Thu Dec 19 18:54:24 2024 UTC+11:00
b) scfg -> System -> Local Time Zone = +01:00
index record 153
when_written 6763D13C 003C Thu Dec 19 18:54:36 2024 UTC+1:00 when_imported 6763D13C 003C Thu Dec 19 18:54:36 2024 UTC+1:00
From what I understand:
6763D130 is time_t in hex, and 0294 is the offset in hex.
Thus, time_t 0x6763D130 (1734594864) plus 0x294 (660) does in fact equal
Thu Dec 19 18:54:24 2024 UTC+11:00
However, time_t 0x6763D13C (1734594876) plus 0x3c (60) does *not* equal
Thu Dec 19 18:54:36 2024 UTC+1:00
I looked into your code, and the problem (I think anyway) is in ctime_r (datawrap.c) if the expectation that Sync returns stored times in a UTC string representation (that is then modified by scfg -> System ->Local Time Zone).
If the expection that sync returns times in "local time" (from ctime_r()), then if you want to present times as per scfg -> System -> Local Time Zone, then the result of ctime() shouldnt be used (for example in smbdump.c#124)?
While sync is correctly storing time_t as a correct UTC time (for these messages anyway, which where created 12s apart and confirmed above) - when ctime() converts the time_t int back to a string, it is presenting a "local time" string, not a "UTC time" string.
Thus, calling the return of ctime() as a time in the timezone configured in scfg - System -> Local time Zone - is that what you intended? (which is what ctime() and smb_zonestr() is presenting).
I hope this makes sense. Ultimately, I dont know why 1734594876+60 should be presented as "Thu Dec 19 18:54:36 2024 UTC+1:00", and further calculations are made from it (generating "10 hrs from now" comments when reading messages) which is simply not true.
Following on from my previous message, I think I understand what is going on - doesnt make sense to me why, but I get it.
I raised this thread, because a message I just saved with save_msg(), when immediately read would display a message of "11hrs from now".
I looked further into the code, and understand what age_of_posted_item() with smb_tzutc() is doing.
When Sync starts, xpTimeZone_local() shows the offset from UTC, and sends a warning message on the console on startup, in my case its 660.
When saving a message with save_msg(), when_written_time, is populated with time() if no value is provided, which is the UTC time when the function is called.
When displaying the message, the age is calculated between the value of when_written_time (which is utc), and time() [utc] minus xpTimeZone_local() plus an offset (which might be negative) derived from scfg -> System -> Local Time Zone.
Since I had UTC there, it would be zero, so the age of the
messages is immediately 660s old (utc minus 660 plus 0).
Thus when when scfg -> System ->Local Time Zone equals xpTimeZone_Local(), they cancel each other out and age_of_posted_item() is truely however many seconds ago the message was stored. (utc minus 660 plus 660).
If this is what is intended, then OK, I get it. Why somebody would find this useful I guess I dont understand.
Thus when when scfg -> System ->Local Time Zone equals xpTimeZone_Local(), they cancel each other out and age_of_posted_item() is truely however many seconds ago the message was stored. (utc minus 660 plus 660).
If this is what is intended, then OK, I get it. Why somebody would find this useful I guess I dont understand.
Re: JS Object save_msg()
By: deon to Digital Man on Thu Dec 19 2024 08:45 pm
Thus when when scfg -> System ->Local Time Zone equals xpTimeZone_Local(), they cancel each other out and age_of_posted_item() is truely however many seconds ago the message was stored. (utc minus 660 plus 660).
If this is what is intended, then OK, I get it. Why somebody would find this useful I guess I dont understand.
The time zone offsets are applied to calculate the age of posted messages to account for messages received via message networks: the when_written_time value is a time_t, in UTC, but represents the parsed date/time from the originating message header (which is the local time for the time zone of the poster): it's not necessarily the current UTC time at the time of posting when posted from a different time zone.
So yes, the adjustments to calculate the message age look unnecessary when considering only locally posted messages but make sense when considering network-posted messages.
Looking/thinking more about the use of time_t for storage of date/time for posted messages because your questions (thank you for those), I do see a flaw, after all these years: If the system (OS) time zone is changed (beyond just annual daylight versus standard time changes), then the stored "when_written_time" values in message headers no longer actually reflect the "wallclock time" of the posted message, as was the intent.
For example, I post/save a message right now and it reflects (correctly): Dec-20-2024 12:30 PM, PST and it stores the current time_t value that represents that (as can be seen with ctime, etc.).
However, if I move to BBS to the U.S. east coast and change the system (OS) time zone setting that message is now reported as having been posted at: Dec-20-2024 03:30 PM, PST
If someone posted at 4AM in their local
time, that's usually what I want to see in the message header.
Re: JS Object save_msg()
By: Digital Man to deon on Fri Dec 20 2024 12:37 pm
Howdy,
Looking/thinking more about the use of time_t for storage of date/time for posted messages because your questions (thank you for those), I do see a flaw, after all these years: If the system (OS) time zone is changed (beyond just annual daylight versus standard time changes), then the stored "when_written_time" values in message headers no longer actually reflect the "wallclock time" of the posted message, as was the intent.
For example, I post/save a message right now and it reflects (correctly): Dec-20-2024 12:30 PM, PST and it stores the current time_t value that represents that (as can be seen with ctime, etc.).
However, if I move to BBS to the U.S. east coast and change the system (OS) time zone setting that message is now reported as having been posted at: Dec-20-2024 03:30 PM, PST
Actually, I was pleased to see that messages are stored in time_t, and in fact the "wall time" you mention is still valid? I think its the right approach, because it doesnt represent that actual time a message was written (on your system anyway).
IE: You posting a message at 12:30pm PST, isnt that 3:30pm on the east coast? Its that PST (aka scfg -> system -> local time zone) setting that is messing things. (I think - because that text is appended to the ctime() results.)
If that was removed, (or rather changed to control how time is *displayed* only), and then reading messages can still be displayed in PST (if that is what you wanted), or shown "local" time zone (EST? dont know what east cost timezone is called).
(Additionally, it should be easier to allow users to show times in "their" local time - if it wasnt PST/EST, or for that matter AEDT/+11:00 then you use the users preferred timezone, instead of the system one when rendering a date.)
IE: Messages, as written as stored in utc (time_t), no change there.
When displaying a message, you set the timezone accordingly, then use ctime()? (Dont know the c/c++ function to display time in a differnet timezone, but I know it is manipulated by TZ environment variable right?
Showing age (which I do like in Sync), its easy to figure out how many hours ago something was posted, by using time_t (utc ints).
If someone posted at 4AM in their local
time, that's usually what I want to see in the message header.
That I agree. Hence why I actually like the time offset appended to the time (+11:00 in my case). When I see a message as ... 04:00:00 +06:00, and its 6pm for me, I know immediately that it was written at 9am my time, and thus 9 hrs ago. But I do agree the timezone string looks good too, just harder to the math.
IE: You posting a message at 12:30pm PST, isnt that 3:30pm on the east coast? Its that PST (aka scfg -> system -> local time zone) setting that is messing things. (I think - because that text is appended to the ctime() results.)
That's how messages are sent over message networks though, the date/time stamp in the message header is the *local* time at site of the posting.
Re: JS Object save_msg()
By: Digital Man to deon on Sun Dec 22 2024 10:14 am
Howdy,
IE: You posting a message at 12:30pm PST, isnt that 3:30pm on the east coast? Its that PST (aka scfg -> system -> local time zone) setting that is messing things. (I think - because that text is appended to the ctime() results.)
That's how messages are sent over message networks though, the date/time stamp in the message header is the *local* time at site of the posting.
I'm not following your point.
I'll use an example, and for now pretend we didnt have scfg -> System -> Local Time Zone - we just used ctime(), and our OS's are set to our current time zone.
If you wrote your message at 22 Dec 2024 13:30 PST (or UTC-8:00), which is time_t 1734759000 (on your system). It would display on you system as that, and if you exported the mail over the network, it would be exported as 22 Dec 2024 13:30 (string) with a TZUTC string of -0800.
When that message arrived on my system (UTC+11:00), it would be presented to me as the same time (UTC-08:00), and converted to the same time_t 1734759000.
Your change to when_written_time might affect those playing with the JS (like me), where I'm playing with dates/times for sorting and filtering and also referencing that back to the result of time(). :( I probably dont really have a need to reference them back to time(), but now I cant if I wanted to? EG: Not making a message visable until when_written_time < time().
I see you've changed when_import_time to now have a bit version of a date :( it'd make that harder to show messages in a per user timezone, since you'd have to write the math functions to achieve the above now(?), instead of a thread safe version of tzset() (I think you have something?) and the OS/strftime doing it?
A sysop can remove the time zone portion of the message header display ifhey
prefer, but I like it. If a message is posted at 4AM EST, I want to see that when I read the message (not 12AM PST).
No, it would not. The mktime() standard C library function uses *your* local time zone (not mine) in the conversion to time_t. There isn't a standard C runtime library function that takes a broken-down date/time and converts it to a time_t using an arbitrary (user supplied) time zone. The rest of your message seemed dependant on this first incorrect assumption.
No, it doesn't. The JS when_written_time property is still a time_t representation - I do the conversion (encoding upon assignemnt, decoding upon use) to the SMB date storage automatically for you.
Re: JS Object save_msg()
By: Digital Man to deon on Sat Dec 21 2024 04:59 pm
Howdy,
No, it doesn't. The JS when_written_time property is still a time_t representation - I do the conversion (encoding upon assignemnt, decoding upon use) to the SMB date storage automatically for you.
Actually I was refering to the post implementation of your changes to when_written_time - from your commit example:
Here's an example from smbutil v of a message header posted after this change:
when_written 03292595 41E0 Fri Dec 20 18:22:21 2024 PST
0x03292595 (53028245) is the now new value of when_written_time right?
But I think I get you, when I read a when_written_time, it'll convert back to time_t value like time()?
Sysop: | Lmorchard |
---|---|
Location: | Portland, OR |
Users: | 63 |
Nodes: | 16 (0 / 16) |
Uptime: | 241:36:51 |
Calls: | 394 |
Files: | 1 |
Messages: | 24,804 |