Closed Bug 1329841 Opened 3 years ago Closed 3 years ago

Re-implement kDateFormatYearMonth and kDateFormatWeekday

Categories

(Core :: Internationalization, defect, P3)

defect

Tracking

()

RESOLVED FIXED
mozilla54
Tracking Status
firefox54 --- fixed

People

(Reporter: emk, Assigned: gmoore)

References

Details

(Keywords: dev-doc-needed, good-first-bug)

Attachments

(1 file, 3 obsolete files)

+++ This bug was initially created as a clone of Bug #1301640 +++

kDateFormatYearMonth and kDateFormatWeekday are removed because they are not used in Firefox tree, but they are still used in Thunderbird. We should consider re-implementing them.

Note: although Mozilla-employees are not supposed to care about Thunderbird, I'm not a Mozilla-employee :)
(In reply to Jorg K (GMT+1) from bug 1301640 comment #161)
> Can you put support back? Does ICU support this? Here
> https://dxr.mozilla.org/comm-central/rev/0d823cf54df53e0cea75a74adebace956bd333d8/mozilla/intl/locale/DateTimeFormatICU.cpp#82
> I can only see three types: long, short, none.

We can use UDAT_PATTERN to implement custom format.
No longer blocks: 1325751
No longer depends on: 1215247, 1325792, 1325745
Gregory, are you interested in working on this?
Flags: needinfo?(olucafont6)
Yeah, definitely. By the way, in the cases where we use UDAT_PATTERN we will need to have separate UDateFormat objects for the date and the time. Therefore when the user chooses kDateFormatYearMonth or kDateFormatWeekday as the date format, and something other than UDAT_NONE for the time format, we won't have the "at" connecting the date and time. Not sure if that matters or not.
Flags: needinfo?(olucafont6)
Here's the patch; let me know if you see any problems.

Also, should we remove the kTimeFormatSecondsForce24Hour and kTimeFormatNoSecondsForce24Hour options from nsIScriptableDateFormat.idl?:
https://dxr.mozilla.org/mozilla-central/source/intl/locale/nsIScriptableDateFormat.idl#27
We no longer support those options. As far as I know Thunderbird isn't using those options either.
Attachment #8825982 - Flags: review?(VYV03354)
Comment on attachment 8825982 [details] [diff] [review]
Added support into DateTimeFormat*.cpp for kDateFormatYearMonth and kDateFormatWeekday date format selectors.

Review of attachment 8825982 [details] [diff] [review]:
-----------------------------------------------------------------

::: intl/locale/DateTimeFormatICU.cpp
@@ +128,5 @@
> +    dateTimeFormat = udat_open(timeStyle, dateStyle, mLocale->get(), nullptr, -1, nullptr, -1, &status);
> +  }
> +  else {
> +    if (aDateFormatSelector == kDateFormatYearMonth) {
> +      dateFormat = udat_open(UDAT_PATTERN, dateStyle, mLocale->get(), nullptr, -1, L"yyyy/MM", -1, &status);

Using a literal pattern like this doesn't account for the fact that the locale might call for a different separator (or even a different ordering). A better solution, I think, would be to use udatpg_getBestPattern to convert a skeleton such as "yyyyMM" into the appropriate pattern for the locale.
(In reply to Gregory Moore from comment #3)
> Yeah, definitely. By the way, in the cases where we use UDAT_PATTERN we will
> need to have separate UDateFormat objects for the date and the time.
> Therefore when the user chooses kDateFormatYearMonth or kDateFormatWeekday
> as the date format, and something other than UDAT_NONE for the time format,
> we won't have the "at" connecting the date and time. Not sure if that
> matters or not.

It should be possible to improve this by getting the pattern from the chosen time style (udat_toPattern), extract the pattern skeleton from that (udatpg_getSkeleton), and combine that with the appropriate skeleton for the date part; then use udatpg_getBestPattern to turn the combined date+time skeleton back into a locale-specific pattern.
Would it be hard for Thunderbird to move to use Intl API from JS? I feel like we should aim to move away from doing such front-end formatting in the C++ code.
Jorg, see comment #7. If you move to use JS Intl API, I'll close this bug as WONTFIX.
Flags: needinfo?(jorgk)
Frankly, I don't know. We do a whole lot of date/time formatting in C++ code. That can't be changed to JS in a hurry. What is that JS Intl API? Can that be called from C++ without a performance hit? We have this date column and if the e-mail folder/view has a bazillion messages, the date formatting is called an awful lot.

Counter question: How hard would it be to move FF certificate details to that interface. Now multiply by eight call sites we have and the staff ratio "FF vs. TB". And, as I said, keep in mind that FF would display *one* certificate date whereas we display dates for many messages.

As I said before, those two additional date formats aren't essential, but as there was will to re-implement them, they would be nice to have to keep supporting the (few?) users who currently use them. There don't seem to be a lot of changes in the patch and exercising UDAT_PATTERN might be a good thing to have in the box.
Flags: needinfo?(jorgk)
> What is that JS Intl API?

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_identification_and_negotiation

spec:

https://www.ecma-international.org/ecma-402/3.0/index.html

> As I said before, those two additional date formats aren't essential, but as there was will to re-implement them, they would be nice to have to keep supporting the (few?) users who currently use them.

Yeah, makes sense.

I definitely will want to move the certificate call eventually, but until then, we can keep the C++ APIs and since the patch is here, we can as well fix the regression.

But I would recommend TB to start moving Intl formatting toward JS as I do believe that we will want to move Gecko Intl to be in JS.
(In reply to Jonathan Kew (:jfkthame) from comment #5)
> Using a literal pattern like this doesn't account for the fact that the
> locale might call for a different separator (or even a different ordering).
> A better solution, I think, would be to use udatpg_getBestPattern to convert
> a skeleton such as "yyyyMM" into the appropriate pattern for the locale.

Okay, thanks for the information. That's a good idea. 

However, if you look at the old nsDateTimeFormat*.cpp files, they all use literal patterns (such as "yyyy/MM") for kDateFormatYearMonth. So it doesn't seem like we would be really be regressing in that respect (and it would be simpler). However, yeah, it would be more correct if we did it the way you mentioned.

It seems like it's okay to go ahead with this patch for now. Should I work on implementing the improvements mentioned by :jfkthame in comment 5 and comment 6, or should we just go with the patch how it is?
Flags: needinfo?(VYV03354)
(In reply to Gregory Moore from comment #4)
> Also, should we remove the kTimeFormatSecondsForce24Hour and
> kTimeFormatNoSecondsForce24Hour options from nsIScriptableDateFormat.idl?:
> https://dxr.mozilla.org/mozilla-central/source/intl/locale/
> nsIScriptableDateFormat.idl#27
> We no longer support those options. As far as I know Thunderbird isn't using
> those options either.

Let's remove unused constants.

(In reply to Gregory Moore from comment #11)
> It seems like it's okay to go ahead with this patch for now. Should I work
> on implementing the improvements mentioned by :jfkthame in comment 5 and
> comment 6, or should we just go with the patch how it is?

I think you should implement the improvement now rather than making a double effort.
Flags: needinfo?(VYV03354)
Alright, here is a patch with the improvements discussed above implemented. It's kind of messy; there's a lot of checking for buffer overflows and stuff, so there might be some improvements to be made there. It seems to work though. Let me know if you have any suggestions. Thanks.
Attachment #8825982 - Attachment is obsolete: true
Attachment #8825982 - Flags: review?(VYV03354)
Flags: needinfo?(VYV03354)
Comment on attachment 8835132 [details] [diff] [review]
Changed code to get the best format pattern from a skeleton, instead of using a literal pattern.

Thank you for the updated patch.

You can just remove DateTimeFormatUnix.cpp (and optionally rename DateTimeFormatICU.cpp) because bug 1215247 has been (finally!) fixed.
Flags: needinfo?(VYV03354)
Also, please add some basic unit tests for kDateFormatYearMonth and kDateFormatWeekday.
(In reply to Masatoshi Kimura [:emk] from comment #14)
> You can just remove DateTimeFormatUnix.cpp (and optionally rename
> DateTimeFormatICU.cpp) because bug 1215247 has been (finally!) fixed.

Okay cool, I will do that.

> Also, please add some basic unit tests for kDateFormatYearMonth and
> kDateFormatWeekday.

Okay. What kind of tests should I include? So far I'm thinking:
a) Test Format*Time() (one of them) with aDateFormatSelector = kDateFormatYearMonth, and set aTimeFormatSelector to each of its possible values.
b) Test Format*Time() with aDateFormatSelector = kDateFormatWeekday, and set aTimeFormatSelector to each of its possible values.
We would set mLocale to a fixed value ("en-US") before the tests as well.

Besides that I'm not really sure what else to test though. I could try different time values but I'm not sure how much that would matter. Let me know if there are other cases I should test or if some of mine are unnecessary. Thanks.
Flags: needinfo?(VYV03354)
(In reply to Gregory Moore from comment #16)
> Okay. What kind of tests should I include? So far I'm thinking:
> a) Test Format*Time() (one of them) with aDateFormatSelector =
> kDateFormatYearMonth, and set aTimeFormatSelector to each of its possible
> values.
> b) Test Format*Time() with aDateFormatSelector = kDateFormatWeekday, and set
> aTimeFormatSelector to each of its possible values.
> We would set mLocale to a fixed value ("en-US") before the tests as well.

I think this is sufficient.
Flags: needinfo?(VYV03354)
Okay, here is the updated patch. By the way, in the calls to udat_toPattern(), we are passing in TRUE for the localized argument, which tells it to localize the pattern. Since we are just turning the pattern into a skeleton after this, it doesn't really seems like it matters what this is set to (and if I change it to FALSE, I still seem to get the same results). I just wanted to check if it would possibly make more sense (or be more efficient) to pass in FALSE. 

Also, should I just get rid of the PATTERN_SKELETON_INITIAL_LEN #define, and replace it's uses with DATETIME_FORMAT_INITIAL_LEN? I think when I originally wrote that I thought it might have a smaller value than 127, but since DATETIME_FORMAT_INITIAL_LEN is also 127, we could probably just have a single define. Let me know, thanks.
Attachment #8835132 - Attachment is obsolete: true
Flags: needinfo?(VYV03354)
Attachment #8836247 - Flags: review?(VYV03354)
Comment on attachment 8836247 [details] [diff] [review]
Added unit test and removed DateTimeFormatUnix.cpp.

Review of attachment 8836247 [details] [diff] [review]:
-----------------------------------------------------------------

(In reply to Gregory Moore from comment #18)
> Created attachment 8836247 [details] [diff] [review]
> Added unit test and removed DateTimeFormatUnix.cpp.
> 
> Okay, here is the updated patch. By the way, in the calls to
> udat_toPattern(), we are passing in TRUE for the localized argument, which
> tells it to localize the pattern. Since we are just turning the pattern into
> a skeleton after this, it doesn't really seems like it matters what this is
> set to (and if I change it to FALSE, I still seem to get the same results).
> I just wanted to check if it would possibly make more sense (or be more
> efficient) to pass in FALSE. 

udat_toPattern uses toLocalizedPattern if localized is TRUE. Otherwise it uses toPattern. But toLocalizedPattern and toPattern have no difference unless you set localized pattern characters:
http://www.icu-project.org/apiref/icu4c/classicu_1_1SimpleDateFormat.html#a48fd316bf28541f20449050bde094855
So you can use FALSE to make the function a bit faster.

> Also, should I just get rid of the PATTERN_SKELETON_INITIAL_LEN #define, and
> replace it's uses with DATETIME_FORMAT_INITIAL_LEN? I think when I
> originally wrote that I thought it might have a smaller value than 127, but
> since DATETIME_FORMAT_INITIAL_LEN is also 127, we could probably just have a
> single define. Let me know, thanks.

I think you can unify defines. Also, you should use const instead of #define.
Attachment #8836247 - Flags: review?(VYV03354) → review+
You don't have to request ni every time you ask.
Flags: needinfo?(VYV03354)
(In reply to Masatoshi Kimura [:emk] from comment #20)
> You don't have to request ni every time you ask.

Oh okay, sorry about that. Here is the patch with the changes. Thanks.
Attachment #8836247 - Attachment is obsolete: true
Pushed by VYV03354@nifty.ne.jp:
https://hg.mozilla.org/integration/mozilla-inbound/rev/89dd7740d001
Added support into DateTimeFormat*.cpp for kDateFormatYearMonth and kDateFormatWeekday date format selectors. r=emk
Assignee: nobody → olucafont6
Status: NEW → ASSIGNED
https://hg.mozilla.org/mozilla-central/rev/89dd7740d001
Status: ASSIGNED → RESOLVED
Closed: 3 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla54
Gregory and Masatoshi-san: Many thanks for implementing this.

With the latest build of Thunderbird I set mail.ui.display.dateformat.thisweek to 4. So for messages received this week I now see for example "Sun 17:41" since Sunday was yesterday.
Depends on: 1343766
You need to log in before you can comment on or make changes to this bug.