Bug 1329841 - Added support into DateTimeFormat*.cpp for kDateFormatYearMonth and kDateFormatWeekday date format selectors. r=emk
authorGregory Moore <olucafont6@yahoo.com>
Wed, 08 Feb 2017 14:08:30 -0800
changeset 391432 89dd7740d00168b8d2a71906024e8c26b72af4ac
parent 391424 80faf8e53b8267235fa512424ef161b5129f00d7
child 391433 fdc2509c3737e5236d6c2097ec4ca7102ca7a0e9
push id1468
push userasasaki@mozilla.com
push dateMon, 05 Jun 2017 19:31:07 +0000
treeherdermozilla-release@0641fc6ee9d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemk
bugs1329841
milestone54.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1329841 - Added support into DateTimeFormat*.cpp for kDateFormatYearMonth and kDateFormatWeekday date format selectors. r=emk MozReview-Commit-ID: 5LpCbpTUMKw
intl/locale/DateTimeFormat.cpp
intl/locale/DateTimeFormat.h
intl/locale/DateTimeFormatICU.cpp
intl/locale/DateTimeFormatUnix.cpp
intl/locale/moz.build
intl/locale/nsIScriptableDateFormat.idl
intl/locale/tests/gtest/TestDateTimeFormat.cpp
rename from intl/locale/DateTimeFormatICU.cpp
rename to intl/locale/DateTimeFormat.cpp
--- a/intl/locale/DateTimeFormatICU.cpp
+++ b/intl/locale/DateTimeFormat.cpp
@@ -3,16 +3,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "DateTimeFormat.h"
 #include "nsCOMPtr.h"
 #include "nsIServiceManager.h"
 #include "nsILocaleService.h"
+#include "unicode/udatpg.h"
 
 namespace mozilla {
 
 nsCString* DateTimeFormat::mLocale = nullptr;
 
 /*static*/ nsresult
 DateTimeFormat::Initialize()
 {
@@ -74,17 +75,17 @@ DateTimeFormat::FormatPRExplodedTime(con
 // performs a locale sensitive date formatting operation on the UDate parameter
 /*static*/ nsresult
 DateTimeFormat::FormatUDateTime(const nsDateFormatSelector aDateFormatSelector,
                                 const nsTimeFormatSelector aTimeFormatSelector,
                                 const UDate aUDateTime,
                                 const PRTimeParameters* aTimeParameters,
                                 nsAString& aStringOut)
 {
-#define DATETIME_FORMAT_INITIAL_LEN 127
+  const int32_t DATETIME_FORMAT_INITIAL_LEN = 127;
   int32_t dateTimeLen = 0;
   nsresult rv = NS_OK;
 
   // return, nothing to format
   if (aDateFormatSelector == kDateFormatNone && aTimeFormatSelector == kTimeFormatNone) {
     aStringOut.Truncate();
     return NS_OK;
   }
@@ -100,16 +101,20 @@ DateTimeFormat::FormatUDateTime(const ns
   UDateFormatStyle dateStyle;
   switch (aDateFormatSelector) {
     case kDateFormatLong:
       dateStyle = UDAT_LONG;
       break;
     case kDateFormatShort:
       dateStyle = UDAT_SHORT;
       break;
+    case kDateFormatYearMonth:
+    case kDateFormatWeekday:
+      dateStyle = UDAT_PATTERN;
+      break;
     case kDateFormatNone:
       dateStyle = UDAT_NONE;
       break;
     default:
       NS_ERROR("Unknown nsDateFormatSelector");
       return NS_ERROR_ILLEGAL_VALUE;
   }
 
@@ -127,33 +132,95 @@ DateTimeFormat::FormatUDateTime(const ns
       break;
     default:
       NS_ERROR("Unknown nsTimeFormatSelector");
       return NS_ERROR_ILLEGAL_VALUE;
   }
 
   // generate date/time string
 
-  UErrorCode status = U_ZERO_ERROR;
-
-  UDateFormat* dateTimeFormat;
+  nsAutoString timeZoneID(u"GMT");
   if (aTimeParameters) {
-    nsAutoString timeZoneID(u"GMT");
-
     int32_t totalOffsetMinutes = (aTimeParameters->tp_gmt_offset + aTimeParameters->tp_dst_offset) / 60;
     if (totalOffsetMinutes != 0) {
       char sign = totalOffsetMinutes < 0 ? '-' : '+';
       int32_t hours = abs(totalOffsetMinutes) / 60;
       int32_t minutes = abs(totalOffsetMinutes) % 60;
       timeZoneID.AppendPrintf("%c%02d:%02d", sign, hours, minutes);
     }
+  }
 
-    dateTimeFormat = udat_open(timeStyle, dateStyle, mLocale->get(), reinterpret_cast<const UChar*>(timeZoneID.BeginReading()), timeZoneID.Length(), nullptr, -1, &status);
+  UErrorCode status = U_ZERO_ERROR;
+
+  UDateFormat* dateTimeFormat;
+  if (dateStyle == UDAT_PATTERN) {
+    nsAutoString pattern;
+
+    dateTimeFormat = udat_open(timeStyle, UDAT_NONE, mLocale->get(), nullptr, -1, nullptr, -1, &status);
+
+    if (U_SUCCESS(status) && dateTimeFormat) {
+      int32_t patternLength;
+      if (timeStyle != UDAT_NONE) {
+        pattern.SetLength(DATETIME_FORMAT_INITIAL_LEN);
+        patternLength = udat_toPattern(dateTimeFormat, FALSE, reinterpret_cast<UChar*>(pattern.BeginWriting()), DATETIME_FORMAT_INITIAL_LEN, &status);
+        pattern.SetLength(patternLength);
+
+        if (status == U_BUFFER_OVERFLOW_ERROR) {
+          status = U_ZERO_ERROR;
+          udat_toPattern(dateTimeFormat, FALSE, reinterpret_cast<UChar*>(pattern.BeginWriting()), patternLength, &status);
+        }
+      }
+
+      nsAutoString skeleton(aDateFormatSelector == kDateFormatYearMonth ? u"yyyyMM " : u"EEE ");
+      int32_t dateSkeletonLen = skeleton.Length();
+
+      if (timeStyle != UDAT_NONE) {
+        skeleton.SetLength(DATETIME_FORMAT_INITIAL_LEN);
+        int32_t skeletonLength = udatpg_getSkeleton(nullptr, reinterpret_cast<const UChar*>(pattern.BeginReading()), patternLength,
+          reinterpret_cast<UChar*>(skeleton.BeginWriting() + dateSkeletonLen), DATETIME_FORMAT_INITIAL_LEN - dateSkeletonLen, &status);
+        skeleton.SetLength(dateSkeletonLen + skeletonLength);
+
+        if (status == U_BUFFER_OVERFLOW_ERROR) {
+          status = U_ZERO_ERROR;
+          udatpg_getSkeleton(nullptr, reinterpret_cast<const UChar*>(pattern.BeginReading()), patternLength,
+            reinterpret_cast<UChar*>(skeleton.BeginWriting() + dateSkeletonLen), dateSkeletonLen + skeletonLength, &status);
+        }
+      }
+
+      UDateTimePatternGenerator* patternGenerator = udatpg_open(mLocale->get(), &status);
+      if (U_SUCCESS(status)) {
+        pattern.SetLength(DATETIME_FORMAT_INITIAL_LEN);
+        patternLength = udatpg_getBestPattern(patternGenerator, reinterpret_cast<const UChar*>(skeleton.BeginReading()), skeleton.Length(), 
+                                              reinterpret_cast<UChar*>(pattern.BeginWriting()), DATETIME_FORMAT_INITIAL_LEN, &status);
+        pattern.SetLength(patternLength);
+
+        if (status == U_BUFFER_OVERFLOW_ERROR) {
+          status = U_ZERO_ERROR;
+          udatpg_getBestPattern(patternGenerator, reinterpret_cast<const UChar*>(skeleton.BeginReading()), skeleton.Length(),
+                                reinterpret_cast<UChar*>(pattern.BeginWriting()), patternLength, &status);
+        }
+      }
+
+      udatpg_close(patternGenerator);
+    }
+
+    udat_close(dateTimeFormat);
+
+    if (aTimeParameters) {
+      dateTimeFormat = udat_open(UDAT_PATTERN, UDAT_PATTERN, mLocale->get(), reinterpret_cast<const UChar*>(timeZoneID.BeginReading()), timeZoneID.Length(), 
+                                 reinterpret_cast<const UChar*>(pattern.BeginReading()), pattern.Length(), &status);
+    } else {
+      dateTimeFormat = udat_open(UDAT_PATTERN, UDAT_PATTERN, mLocale->get(), nullptr, -1, reinterpret_cast<const UChar*>(pattern.BeginReading()), pattern.Length(), &status);
+    }
   } else {
-    dateTimeFormat = udat_open(timeStyle, dateStyle, mLocale->get(), nullptr, -1, nullptr, -1, &status);
+    if (aTimeParameters) {
+      dateTimeFormat = udat_open(timeStyle, dateStyle, mLocale->get(), reinterpret_cast<const UChar*>(timeZoneID.BeginReading()), timeZoneID.Length(), nullptr, -1, &status);
+    } else {
+      dateTimeFormat = udat_open(timeStyle, dateStyle, mLocale->get(), nullptr, -1, nullptr, -1, &status);
+    }
   }
 
   if (U_SUCCESS(status) && dateTimeFormat) {
     aStringOut.SetLength(DATETIME_FORMAT_INITIAL_LEN);
     dateTimeLen = udat_format(dateTimeFormat, aUDateTime, reinterpret_cast<UChar*>(aStringOut.BeginWriting()), DATETIME_FORMAT_INITIAL_LEN, nullptr, &status);
     aStringOut.SetLength(dateTimeLen);
 
     if (status == U_BUFFER_OVERFLOW_ERROR) {
--- a/intl/locale/DateTimeFormat.h
+++ b/intl/locale/DateTimeFormat.h
@@ -3,27 +3,21 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_DateTimeFormat_h
 #define mozilla_DateTimeFormat_h
 
 #include <time.h>
+#include "gtest/MozGtestFriend.h"
 #include "nsIScriptableDateFormat.h"
 #include "nsStringGlue.h"
 #include "prtime.h"
-
-#ifndef ENABLE_INTL_API
-#include "nsCOMPtr.h"
-#include "nsIUnicodeDecoder.h"
-#else
-#include "gtest/MozGtestFriend.h"
 #include "unicode/udat.h"
-#endif
 
 namespace mozilla {
 
 class DateTimeFormat {
 public:
   // performs a locale sensitive date formatting operation on the time_t parameter
   static nsresult FormatTime(const nsDateFormatSelector aDateFormatSelector,
                              const nsTimeFormatSelector aTimeFormatSelector,
@@ -44,37 +38,24 @@ public:
 
   static void Shutdown();
 
 private:
   DateTimeFormat() = delete;
 
   static nsresult Initialize();
 
-#ifdef ENABLE_INTL_API
   FRIEND_TEST(DateTimeFormat, FormatPRExplodedTime);
+  FRIEND_TEST(DateTimeFormat, DateFormatSelectors);
 
   // performs a locale sensitive date formatting operation on the UDate parameter
   static nsresult FormatUDateTime(const nsDateFormatSelector aDateFormatSelector,
                                   const nsTimeFormatSelector aTimeFormatSelector,
                                   const UDate aUDateTime,
                                   const PRTimeParameters* aTimeParameters,
                                   nsAString& aStringOut);
 
   static nsCString* mLocale;
-#else
-  // performs a locale sensitive date formatting operation on the struct tm parameter
-  static nsresult FormatTMTime(const nsDateFormatSelector aDateFormatSelector,
-                               const nsTimeFormatSelector aTimeFormatSelector,
-                               const struct tm* aTmTime,
-                               nsAString& aStringOut);
-
-  static void LocalePreferred24hour();
-
-  static bool mLocalePreferred24hour;                       // true if 24 hour format is preferred by current locale
-  static bool mLocaleAMPMfirst;                             // true if AM/PM string is preferred before the time
-  static nsCOMPtr<nsIUnicodeDecoder> mDecoder;
-#endif
 };
 
 }
 
 #endif  /* mozilla_DateTimeFormat_h */
deleted file mode 100644
--- a/intl/locale/DateTimeFormatUnix.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "DateTimeFormat.h"
-#include "plstr.h"
-#include "nsIServiceManager.h"
-#include "nsILocaleService.h"
-#include "nsIPlatformCharset.h"
-#include "mozilla/dom/EncodingUtils.h"
-
-using mozilla::dom::EncodingUtils;
-
-namespace mozilla {
-
-bool DateTimeFormat::mLocalePreferred24hour;
-bool DateTimeFormat::mLocaleAMPMfirst;
-nsCOMPtr<nsIUnicodeDecoder> DateTimeFormat::mDecoder;
-
-/*static*/ nsresult
-DateTimeFormat::Initialize()
-{
-  nsAutoString localeStr;
-  nsAutoCString charset;
-  nsresult rv = NS_OK;
-
-  if (mDecoder) {
-    return NS_OK;
-  }
-
-  charset.AssignLiteral("windows-1252");
-
-  nsCOMPtr<nsILocaleService> localeService =
-    do_GetService(NS_LOCALESERVICE_CONTRACTID, &rv);
-  if (NS_SUCCEEDED(rv)) {
-    nsCOMPtr<nsILocale> appLocale;
-    rv = localeService->GetApplicationLocale(getter_AddRefs(appLocale));
-    if (NS_SUCCEEDED(rv)) {
-      rv = appLocale->GetCategory(NS_LITERAL_STRING("NSILOCALE_TIME##PLATFORM"), localeStr);
-      NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get app locale info");
-    }
-  }
-
-  if (NS_SUCCEEDED(rv) && !localeStr.IsEmpty()) {
-    nsCOMPtr<nsIPlatformCharset> platformCharset = do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv);
-    if (NS_SUCCEEDED(rv)) {
-      nsAutoCString mappedCharset;
-      rv = platformCharset->GetDefaultCharsetForLocale(localeStr, mappedCharset);
-      if (NS_SUCCEEDED(rv)) {
-        charset = mappedCharset;
-      }
-    }
-  }
-
-  mDecoder = EncodingUtils::DecoderForEncoding(charset);
-
-  LocalePreferred24hour();
-
-  return rv;
-}
-
-/*static*/ void
-DateTimeFormat::LocalePreferred24hour()
-{
-  char str[100];
-  time_t tt;
-  struct tm *tmc;
-  int i;
-
-  tt = time(nullptr);
-  tmc = localtime(&tt);
-
-  tmc->tm_hour=22;    // put the test sample hour to 22:00 which is 10PM
-  tmc->tm_min=0;      // set the min & sec other number than '2'
-  tmc->tm_sec=0;
-
-  strftime(str, (size_t)99, "%X", (struct tm *)tmc);
-
-  mLocalePreferred24hour = false;
-  for (i=0; str[i]; i++) {
-    if (str[i] == '2') {    // if there is any '2', that locale use 0-23 time format
-      mLocalePreferred24hour = true;
-      break;
-    }
-  }
-
-  mLocaleAMPMfirst = true;
-  if (mLocalePreferred24hour == false) {
-    if (str[0] && str[0] == '1') { // if the first character is '1' of 10:00,
-			           // AMPM string is located after 10:00
-      mLocaleAMPMfirst = false;
-    }
-  }
-}
-
-/*static*/ nsresult
-DateTimeFormat::FormatTime(const nsDateFormatSelector aDateFormatSelector,
-                           const nsTimeFormatSelector aTimeFormatSelector,
-                           const time_t aTimetTime,
-                           nsAString& aStringOut)
-{
-  struct tm tmTime;
-  memcpy(&tmTime, localtime(&aTimetTime), sizeof(struct tm));
-  return FormatTMTime(aDateFormatSelector, aTimeFormatSelector, &tmTime, aStringOut);
-}
-
-// performs a locale sensitive date formatting operation on the struct tm parameter
-/*static*/ nsresult
-DateTimeFormat::FormatTMTime(const nsDateFormatSelector aDateFormatSelector,
-                             const nsTimeFormatSelector aTimeFormatSelector,
-                             const struct tm* aTmTime,
-                             nsAString& aStringOut)
-{
-#define NSDATETIME_FORMAT_BUFFER_LEN 80
-  char strOut[NSDATETIME_FORMAT_BUFFER_LEN*2];  // buffer for date and time
-  char fmtD[NSDATETIME_FORMAT_BUFFER_LEN], fmtT[NSDATETIME_FORMAT_BUFFER_LEN];
-  nsresult rv;
-
-  // set up locale data
-  (void) Initialize();
-  NS_ENSURE_TRUE(mDecoder, NS_ERROR_NOT_INITIALIZED);
-
-  // set date format
-  if (aDateFormatSelector == kDateFormatLong && aTimeFormatSelector == kTimeFormatSeconds) {
-    PL_strncpy(fmtD, "%c", NSDATETIME_FORMAT_BUFFER_LEN);
-    PL_strncpy(fmtT, "", NSDATETIME_FORMAT_BUFFER_LEN);
-  } else {
-
-    switch (aDateFormatSelector) {
-      case kDateFormatNone:
-        PL_strncpy(fmtD, "", NSDATETIME_FORMAT_BUFFER_LEN);
-        break;
-      case kDateFormatLong:
-      case kDateFormatShort:
-        PL_strncpy(fmtD, "%x", NSDATETIME_FORMAT_BUFFER_LEN);
-        break;
-      default:
-        PL_strncpy(fmtD, "", NSDATETIME_FORMAT_BUFFER_LEN);
-    }
-
-    // set time format
-    switch (aTimeFormatSelector) {
-      case kTimeFormatNone:
-        PL_strncpy(fmtT, "", NSDATETIME_FORMAT_BUFFER_LEN);
-        break;
-      case kTimeFormatSeconds:
-        PL_strncpy(fmtT, "%X", NSDATETIME_FORMAT_BUFFER_LEN);
-        break;
-      case kTimeFormatNoSeconds:
-        PL_strncpy(fmtT,
-                   mLocalePreferred24hour ? "%H:%M" : mLocaleAMPMfirst ? "%p %I:%M" : "%I:%M %p",
-                   NSDATETIME_FORMAT_BUFFER_LEN);
-        break;
-      default:
-        PL_strncpy(fmtT, "", NSDATETIME_FORMAT_BUFFER_LEN);
-    }
-  }
-
-  // generate date/time string
-  if (strlen(fmtD) && strlen(fmtT)) {
-    PL_strncat(fmtD, " ", NSDATETIME_FORMAT_BUFFER_LEN);
-    PL_strncat(fmtD, fmtT, NSDATETIME_FORMAT_BUFFER_LEN);
-    strftime(strOut, NSDATETIME_FORMAT_BUFFER_LEN, fmtD, aTmTime);
-  } else if (strlen(fmtD) && !strlen(fmtT)) {
-    strftime(strOut, NSDATETIME_FORMAT_BUFFER_LEN, fmtD, aTmTime);
-  } else if (!strlen(fmtD) && strlen(fmtT)) {
-    strftime(strOut, NSDATETIME_FORMAT_BUFFER_LEN, fmtT, aTmTime);
-  } else {
-    PL_strncpy(strOut, "", NSDATETIME_FORMAT_BUFFER_LEN);
-  }
-
-  // convert result to unicode
-  int32_t srcLength = (int32_t) strlen(strOut);
-  int32_t unicharLength = NSDATETIME_FORMAT_BUFFER_LEN*2;
-  char16_t unichars[NSDATETIME_FORMAT_BUFFER_LEN*2];   // buffer for date and time
-
-  rv = mDecoder->Convert(strOut, &srcLength, unichars, &unicharLength);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-  aStringOut.Assign(unichars, unicharLength);
-
-  return rv;
-}
-
-// performs a locale sensitive date formatting operation on the PRTime parameter
-/*static*/ nsresult
-DateTimeFormat::FormatPRTime(const nsDateFormatSelector aDateFormatSelector,
-                             const nsTimeFormatSelector aTimeFormatSelector,
-                             const PRTime aPrTime,
-                             nsAString& aStringOut)
-{
-  PRExplodedTime explodedTime;
-  PR_ExplodeTime(aPrTime, PR_LocalTimeParameters, &explodedTime);
-
-  return FormatPRExplodedTime(aDateFormatSelector, aTimeFormatSelector, &explodedTime, aStringOut);
-}
-
-// performs a locale sensitive date formatting operation on the PRExplodedTime parameter
-/*static*/ nsresult
-DateTimeFormat::FormatPRExplodedTime(const nsDateFormatSelector aDateFormatSelector,
-                                     const nsTimeFormatSelector aTimeFormatSelector,
-                                     const PRExplodedTime* aExplodedTime,
-                                     nsAString& aStringOut)
-{
-  struct tm  tmTime;
-  /* be safe and set all members of struct tm to zero
-   *
-   * there are other fields in the tm struct that we aren't setting
-   * (tm_isdst, tm_gmtoff, tm_zone, should we set these?) and since
-   * tmTime is on the stack, it may be filled with garbage, but
-   * the garbage may vary.  (this may explain why some saw bug #10412, and
-   * others did not.
-   *
-   * when tmTime is passed to strftime() with garbage bad things may happen.
-   * see bug #10412
-   */
-  memset( &tmTime, 0, sizeof(tmTime) );
-
-  tmTime.tm_yday = aExplodedTime->tm_yday;
-  tmTime.tm_wday = aExplodedTime->tm_wday;
-  tmTime.tm_year = aExplodedTime->tm_year;
-  tmTime.tm_year -= 1900;
-  tmTime.tm_mon = aExplodedTime->tm_month;
-  tmTime.tm_mday = aExplodedTime->tm_mday;
-  tmTime.tm_hour = aExplodedTime->tm_hour;
-  tmTime.tm_min = aExplodedTime->tm_min;
-  tmTime.tm_sec = aExplodedTime->tm_sec;
-
-  return FormatTMTime(aDateFormatSelector, aTimeFormatSelector, &tmTime, aStringOut);
-}
-
-/*static*/ void
-DateTimeFormat::Shutdown()
-{
-}
-
-}
--- a/intl/locale/moz.build
+++ b/intl/locale/moz.build
@@ -42,34 +42,26 @@ EXPORTS += [
     'nsWin32Locale.h',
 ]
 
 EXPORTS.mozilla.intl += [
     'LocaleService.h',
 ]
 
 UNIFIED_SOURCES += [
+    'DateTimeFormat.cpp',
     'LocaleService.cpp',
     'nsCollation.cpp',
     'nsLanguageAtomService.cpp',
     'nsLocale.cpp',
     'nsLocaleService.cpp',
     'nsScriptableDateFormat.cpp',
     'nsUConvPropertySearch.cpp',
 ]
 
-if CONFIG['ENABLE_INTL_API']:
-    UNIFIED_SOURCES += [
-        'DateTimeFormatICU.cpp',
-    ]
-else:
-    UNIFIED_SOURCES += [
-        'DateTimeFormatUnix.cpp',
-    ]
-
 EXTRA_JS_MODULES += [
     'PluralForm.jsm',
 ]
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '/intl/uconv',
--- a/intl/locale/nsIScriptableDateFormat.idl
+++ b/intl/locale/nsIScriptableDateFormat.idl
@@ -18,19 +18,17 @@ enum
 %}
 
 typedef long nsTimeFormatSelector;
 %{ C++
 enum
 {
     kTimeFormatNone = 0,            // don't include the time in the format string
     kTimeFormatSeconds,             // provides the time format with seconds in the  given locale 
-    kTimeFormatNoSeconds,           // provides the time format without seconds in the given locale 
-    kTimeFormatSecondsForce24Hour,  // forces the time format to use the 24 clock, regardless of the locale conventions
-    kTimeFormatNoSecondsForce24Hour // forces the time format to use the 24 clock, regardless of the locale conventions
+    kTimeFormatNoSeconds            // provides the time format without seconds in the given locale 
 };
 %}
 
 %{C++
 // Define Contractid and CID
 // {2EA2E7D0-4095-11d3-9144-006008A6EDF6}
 #define NS_SCRIPTABLEDATEFORMAT_CID \
 { 0x2ea2e7d0, 0x4095, 0x11d3, { 0x91, 0x44, 0x0, 0x60, 0x8, 0xa6, 0xed, 0xf6 } }
--- a/intl/locale/tests/gtest/TestDateTimeFormat.cpp
+++ b/intl/locale/tests/gtest/TestDateTimeFormat.cpp
@@ -41,9 +41,42 @@ TEST(DateTimeFormat, FormatPRExplodedTim
   ASSERT_STREQ("December 31, 1969 at 5:00:00 PM", NS_ConvertUTF16toUTF8(formattedTime).get());
 
   prExplodedTime = { 0, 0, 47, 14, 31, 11, 1969, 3, 364, { -((10 * 60 * 60) + (13 * 60)), (1 * 60 * 60) } };
   rv = mozilla::DateTimeFormat::FormatPRExplodedTime(kDateFormatLong, kTimeFormatSeconds, &prExplodedTime, formattedTime);
   ASSERT_TRUE(NS_SUCCEEDED(rv));
   ASSERT_STREQ("December 31, 1969 at 2:47:00 PM", NS_ConvertUTF16toUTF8(formattedTime).get());
 }
 
+TEST(DateTimeFormat, DateFormatSelectors) {
+  PRTime prTime = 0;
+  PRExplodedTime prExplodedTime;
+  PR_ExplodeTime(prTime, PR_GMTParameters, &prExplodedTime);
+
+  mozilla::DateTimeFormat::mLocale = new nsCString("en-US");
+
+  nsAutoString formattedTime;
+  nsresult rv = mozilla::DateTimeFormat::FormatPRExplodedTime(kDateFormatYearMonth, kTimeFormatNone, &prExplodedTime, formattedTime);
+  ASSERT_TRUE(NS_SUCCEEDED(rv));
+  ASSERT_STREQ("01/1970", NS_ConvertUTF16toUTF8(formattedTime).get());
+
+  rv = mozilla::DateTimeFormat::FormatPRExplodedTime(kDateFormatYearMonth, kTimeFormatNoSeconds, &prExplodedTime, formattedTime);
+  ASSERT_TRUE(NS_SUCCEEDED(rv));
+  ASSERT_STREQ("01/1970, 12:00 AM", NS_ConvertUTF16toUTF8(formattedTime).get());
+
+  rv = mozilla::DateTimeFormat::FormatPRExplodedTime(kDateFormatYearMonth, kTimeFormatSeconds, &prExplodedTime, formattedTime);
+  ASSERT_TRUE(NS_SUCCEEDED(rv));
+  ASSERT_STREQ("01/1970, 12:00:00 AM", NS_ConvertUTF16toUTF8(formattedTime).get());
+
+  rv = mozilla::DateTimeFormat::FormatPRExplodedTime(kDateFormatWeekday, kTimeFormatNone, &prExplodedTime, formattedTime);
+  ASSERT_TRUE(NS_SUCCEEDED(rv));
+  ASSERT_STREQ("Thu", NS_ConvertUTF16toUTF8(formattedTime).get());
+
+  rv = mozilla::DateTimeFormat::FormatPRExplodedTime(kDateFormatWeekday, kTimeFormatNoSeconds, &prExplodedTime, formattedTime);
+  ASSERT_TRUE(NS_SUCCEEDED(rv));
+  ASSERT_STREQ("Thu 12:00 AM", NS_ConvertUTF16toUTF8(formattedTime).get());
+
+  rv = mozilla::DateTimeFormat::FormatPRExplodedTime(kDateFormatWeekday, kTimeFormatSeconds, &prExplodedTime, formattedTime);
+  ASSERT_TRUE(NS_SUCCEEDED(rv));
+  ASSERT_STREQ("Thu 12:00:00 AM", NS_ConvertUTF16toUTF8(formattedTime).get());
 }
+
+}