nsScriptableDateFormat.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "mozilla/Sprintf.h"
  6. #include "nsILocaleService.h"
  7. #include "nsDateTimeFormatCID.h"
  8. #include "nsIDateTimeFormat.h"
  9. #include "nsIScriptableDateFormat.h"
  10. #include "nsCOMPtr.h"
  11. #include "nsServiceManagerUtils.h"
  12. static NS_DEFINE_CID(kLocaleServiceCID, NS_LOCALESERVICE_CID);
  13. static NS_DEFINE_CID(kDateTimeFormatCID, NS_DATETIMEFORMAT_CID);
  14. class nsScriptableDateFormat : public nsIScriptableDateFormat {
  15. public:
  16. NS_DECL_ISUPPORTS
  17. NS_IMETHOD FormatDateTime(const char16_t *locale,
  18. nsDateFormatSelector dateFormatSelector,
  19. nsTimeFormatSelector timeFormatSelector,
  20. int32_t year,
  21. int32_t month,
  22. int32_t day,
  23. int32_t hour,
  24. int32_t minute,
  25. int32_t second,
  26. char16_t **dateTimeString) override;
  27. NS_IMETHOD FormatDate(const char16_t *locale,
  28. nsDateFormatSelector dateFormatSelector,
  29. int32_t year,
  30. int32_t month,
  31. int32_t day,
  32. char16_t **dateString) override
  33. {return FormatDateTime(locale, dateFormatSelector, kTimeFormatNone,
  34. year, month, day, 0, 0, 0, dateString);}
  35. NS_IMETHOD FormatTime(const char16_t *locale,
  36. nsTimeFormatSelector timeFormatSelector,
  37. int32_t hour,
  38. int32_t minute,
  39. int32_t second,
  40. char16_t **timeString) override
  41. {return FormatDateTime(locale, kDateFormatNone, timeFormatSelector,
  42. 1999, 1, 1, hour, minute, second, timeString);}
  43. nsScriptableDateFormat() {}
  44. private:
  45. nsString mStringOut;
  46. virtual ~nsScriptableDateFormat() {}
  47. };
  48. NS_IMPL_ISUPPORTS(nsScriptableDateFormat, nsIScriptableDateFormat)
  49. NS_IMETHODIMP nsScriptableDateFormat::FormatDateTime(
  50. const char16_t *aLocale,
  51. nsDateFormatSelector dateFormatSelector,
  52. nsTimeFormatSelector timeFormatSelector,
  53. int32_t year,
  54. int32_t month,
  55. int32_t day,
  56. int32_t hour,
  57. int32_t minute,
  58. int32_t second,
  59. char16_t **dateTimeString)
  60. {
  61. // We can't have a valid date with the year, month or day
  62. // being lower than 1.
  63. if (year < 1 || month < 1 || day < 1)
  64. return NS_ERROR_INVALID_ARG;
  65. nsresult rv;
  66. nsAutoString localeName(aLocale);
  67. *dateTimeString = nullptr;
  68. nsCOMPtr<nsILocale> locale;
  69. // re-initialise locale pointer only if the locale was given explicitly
  70. if (!localeName.IsEmpty()) {
  71. // get locale service
  72. nsCOMPtr<nsILocaleService> localeService(do_GetService(kLocaleServiceCID, &rv));
  73. NS_ENSURE_SUCCESS(rv, rv);
  74. // get locale
  75. rv = localeService->NewLocale(localeName, getter_AddRefs(locale));
  76. NS_ENSURE_SUCCESS(rv, rv);
  77. }
  78. nsCOMPtr<nsIDateTimeFormat> dateTimeFormat(do_CreateInstance(kDateTimeFormatCID, &rv));
  79. NS_ENSURE_SUCCESS(rv, rv);
  80. tm tmTime;
  81. time_t timetTime;
  82. memset(&tmTime, 0, sizeof(tmTime));
  83. tmTime.tm_year = year - 1900;
  84. tmTime.tm_mon = month - 1;
  85. tmTime.tm_mday = day;
  86. tmTime.tm_hour = hour;
  87. tmTime.tm_min = minute;
  88. tmTime.tm_sec = second;
  89. tmTime.tm_yday = tmTime.tm_wday = 0;
  90. tmTime.tm_isdst = -1;
  91. timetTime = mktime(&tmTime);
  92. if ((time_t)-1 != timetTime) {
  93. rv = dateTimeFormat->FormatTime(locale, dateFormatSelector, timeFormatSelector,
  94. timetTime, mStringOut);
  95. }
  96. else {
  97. // if mktime fails (e.g. year <= 1970), then try NSPR.
  98. PRTime prtime;
  99. char string[32];
  100. SprintfLiteral(string, "%.2d/%.2d/%d %.2d:%.2d:%.2d", month, day, year, hour, minute, second);
  101. if (PR_SUCCESS != PR_ParseTimeString(string, false, &prtime))
  102. return NS_ERROR_INVALID_ARG;
  103. rv = dateTimeFormat->FormatPRTime(locale, dateFormatSelector, timeFormatSelector,
  104. prtime, mStringOut);
  105. }
  106. if (NS_SUCCEEDED(rv))
  107. *dateTimeString = ToNewUnicode(mStringOut);
  108. return rv;
  109. }
  110. nsresult
  111. NS_NewScriptableDateFormat(nsISupports* aOuter, REFNSIID aIID, void** aResult)
  112. {
  113. if (aOuter)
  114. return NS_ERROR_NO_AGGREGATION;
  115. nsScriptableDateFormat* result = new nsScriptableDateFormat();
  116. if (! result)
  117. return NS_ERROR_OUT_OF_MEMORY;
  118. NS_ADDREF(result);
  119. nsresult rv = result->QueryInterface(aIID, aResult);
  120. NS_RELEASE(result);
  121. return rv;
  122. }