openwebwork / webwork2

Course management front end for WeBWorK
http://webwork.maa.org/wiki/Main_Page
Other
145 stars 165 forks source link

Improvements to date/time string handling. #2263

Closed drgrice1 closed 10 months ago

drgrice1 commented 11 months ago

Many issues with date/time display and parsing have been fixed.

Generally speaking, if the content generator formatDateTime method is used the default timezone and locale should not be overridden, and if the format string is overridden then it should be with one of the localizable DateTime::Locale::FromData methods, datetime_format_short, datetime_format_medium, datetime_format_long, or datetime_format_full, or the course environment variable $studentDateDisplayFormat. If it is a date displayed for students then it should always be $studentDateDisplayFormat.

Note that the order of the arguments for the content generator method and the WeBWorK::Utils formatDateTime methods has been changed. The format string is now the first optional argument (after the required date time epoch), then the timezone and locale are the last two optional arguments.

Also note that the $siteDefaults{locale} setting in site.conf is no more. Now the locale is the same as the $language setting. The previous documentation in site.conf was incorrect on how to determine valid values for this setting, and the stated default value was technically incorrect as well. The DateTime::Locale package does not use what the shell command locale -a shows, and has nothing to do with what locales are available on your system. Technically, the default setting is en-US, not en_US (although the DateTime::Locale does accept underscores and converts them to dashes). A valid way of obtaining available locales is perl -MDateTime::Locale -e 'print join "\n", DateTime::Locale->codes;'. Note that zh-HK and zh-CN are technically not valid codes either (valid codes are zh, zh-Hans-HK, zh-Hant-HK, and zh-Hans-CN), but the DateTime::Locale ignores the territory code and uses zh in both cases. This is the best that can be done in this case, because that is the necessary code to match flatpickr as it does not support any variants.

The default value of $studentDateDisplayFormat is now datetime_format_long, but that can be changed by uncommenting the override in localOverrides.conf (the commented out line there is the old default). This setting can now be configured from the course configuration page as well.

If the WeBWorK::Utils formatDateTime method is used directly, then the timezone and locale should be passed from the course environment. The only exception to this is for set definition files. The timezone can be used, but the locale absolutely can not be. The English locale must be used. The reason for this is that the parseDateTime method from WeBWorK::Utils does not know how to deal with localized date/time strings. As a result if a set is exported with a localized date/time string, then it will not import correctly. Note that currently if a set is exported and the locale is set to the now deleted $siteDefaults{locale} setting, then a warning will be issued if the locale uses multibyte characters for AM/PM, and when the set is imported the dates are incorrect.

There is a new method in WeBWorK::Utils for obtaining the default set due date for newly created sets. It is getDefaultSetDueDate. This method does not use localization and no longer creates a string and then parses it back to an epoch. Instead it works directly with DateTime objects. It does need to parse the $pg{timeAssignDue} course environment variable into its hour and minute parts, but that is the only string parsing it works with. Unfortunately, it was a bad decision to use a string like "11:59pm" for that setting instead of something like minutes into the day, but lots of bad decisions were made (that hindsight reveals were bad).

So now the parseDateTime method is used only for set definition importing, and should never again be used for anything else.