Bug #2829
openPossible 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 10 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 10 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 almost 5 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 almost 5 years ago
What? That should not cause a crash (and it doesn't when I test it).
Updated by Stefan Bn over 4 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 over 4 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.