Bug #2829
Possible bug in Wt::WDateTime
0%
Description
The function Wt::WDateTime::currentDateTime().toLocalTime().toString() seems to return the server time, no matter what locale I set.
I do this in the application object constructor:
Wt::log("notice") << "Server time (UTC) is " << Wt::WDateTime::currentDateTime().toString();
Wt::log("notice") << "Server time (local) is " << Wt::WDateTime::currentDateTime().toLocalTime().toString();
Wt::log("notice") << "Current locale is " << Wt::WLocale::currentLocale().name();
Wt::log("notice") << "Application locale is " << locale().name();
It prints
[2014-Mar-19 17:37:54.365412] 5992 [/ sAbCaewpUIhd7zDH] [notice] "Server time (UTC) is Wed Mar 19 16:37:54 2014"
[2014-Mar-19 17:37:54.378413] 5992 [/ sAbCaewpUIhd7zDH] [notice] "Server time (local) is 2014-03-19 16:37:54"
[2014-Mar-19 17:37:54.393414] 5992 [/ sAbCaewpUIhd7zDH] [notice] "Current locale is nb-NO"
[2014-Mar-19 17:37:54.407415] 5992 [/ sAbCaewpUIhd7zDH] [notice] "Application locale is nb-NO"
I am at UTC+1. I have tried calling Wt::WEnvironment.timeZoneOffset(), and it returns 60. Application.locale().timeZone() returns an empty string.
I have tried with just the default locale, and also with calling setLocale("nb-NO"), setLocale("el-GR"), setLocale("ru-RU"), setLocale("C").
I noticed that the 'heading' from the log contains the correct time. It appears that it is implemented using some boost function.
I really would like my local time to be correct ;). What am I doing wrong?
Updated by Koen Deforche over 8 years ago
- Status changed from New to Feedback
Hey,
Instead of:
Wt::WDateTime::currentDateTime().toLocalTime().toString();
You should use:
Wt::WLocalDateTime::currentDateTime().toString()
WDateTime::toLocalTime() needs detailed locale information to convert a time to local time, whereas WLocalDateTime::currentDateTime() can use the 'current' time offset as passed by the user to convert the local time.
Note that simply using setLocale("nb-NO") only affects language, but not other locale settings (yet; we currently reconsidering if we should adopt std::locale; but currently we avoided it as it's a bug-ridden beast and a tough dependency on many embedded systems, and even if we would it would not help us with time zones since that's not a standardized facet). To set the timezone information needed for your conversion to work, you need to use app->locale().setTimeZone() using a POSIX time zone specification.
We also have a small feature example that shows how to configure the timezone from a drop-down box, which is seeded with information from the browser:
https://github.com/kdeforche/wt/tree/master/examples/feature/locale
(Somehow there is no nice website that translates 'Olson' time zone names into posix time zone strings).
Regards,
koen
Updated by Eivind Midtgård over 8 years ago
Hi Koen,
Thanks, this helps. My needs at the moment are so simple that I can get by by adding the time zone offset to the UTC time.
Regards,
Eivind
Updated by Stefan Bn over 2 years ago
This feedback helped for me as well!
This will crash my software immediately:
WDateTime::currentDateTime().toString("dd.MM.yyyy hh:mm:ss");
while this works:
WLocalDateTime::currentDateTime().toString("dd.MM.yyyy hh:mm:ss");
I can see the difference behind it, but the former statement should at least be safe and not crashing!
Updated by Roel Standaert over 2 years ago
What? That should not cause a crash (and it doesn't when I test it).
Updated by Stefan Bn about 2 years ago
I just came across this at a point where I use WLocalDateTime inside a derived WResource class without any localization references (Wt 4.3.1 using MinGW 9.3.1 on Windows).
This crashes immediately:
WLocalDateTime::currentDateTime().toString("yyyy MMMM dd");
at the return statement in line 64 in WLocalDateTime.C
template<class Duration> date::local_time<typename std::common_type<Duration, std::chrono::minutes>::type> to_local(date::sys_time<Duration> tp) const { using namespace date; using namespace std; using namespace std::chrono; using LT = local_time<typename common_type<Duration, minutes>::type>; return LT{(tp + offset_).time_since_epoch()}; }
while this works: WDateTime::currentDateTime().toString("dd.MM.yyyy hh:mm:ss");
Also see this thread:
https://redmine.webtoolkit.eu/boards/2/topics/16454
Updated by Stefan Bn about 2 years ago
I have a different project and the same behavior as posted before:
This crashes immediately:
WLocalDateTime now = WLocalDateTime::currentDateTime().toString();
when used in a worker thread in a WObject derived class outside a WApplication. In my previous post it happend inside a WResource. Maybe the cause is that it is called outside a WApplication?
now.isValid() returns true, but subsequent .toString() crashes.