OpenCPN Partial API docs
Loading...
Searching...
No Matches
datetime.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * Copyright (C) 2023 by David Register *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, see <https://www.gnu.org/licenses/>. *
16 **************************************************************************/
17
24#include <iomanip>
25#include <sstream>
26
27#include <wx/tokenzr.h>
28#if wxCHECK_VERSION(3, 1, 6)
29#include <wx/uilocale.h>
30#endif
31
32#ifdef __ANDROID__
33#include "androidUTIL.h"
34#endif
35
36#include "model/datetime.h"
37#include "ocpn_plugin.h"
38
39namespace ocpn {
40
41wxString getUsrDateTimeFormat() { return ::g_datetime_format; }
42
43// date/time in the desired time zone format.
44wxString toUsrDateTimeFormat(const wxDateTime date_time,
46#if wxCHECK_VERSION(3, 1, 6)
47 ,
48 const wxUILocale& locale
49#endif
50) {
51 wxDateTime t(date_time);
52 wxString effective_time_zone = options.time_zone;
53 if (effective_time_zone == "") {
54 effective_time_zone = ::g_datetime_format;
55 }
56 if (effective_time_zone == "") {
57 effective_time_zone = "UTC";
58 }
59#ifdef __ANDROID__
60 wxString aform = androidGetLocalizedDateTime(options, date_time);
61 if (!aform.IsEmpty()) return aform;
62#endif
63
64 // Define a map for custom format specifiers.
65 std::vector<std::pair<wxString, wxString>> formatMap = {
66#if wxCHECK_VERSION(3, 1, 6)
67 // Note: the GetInfo() method may return special unicode characters, such
68 // as narrow no-break space (U+202F).
69 {"$long_date_time", locale.GetInfo(wxLOCALE_LONG_DATE_FMT) + " " +
70 locale.GetInfo(wxLOCALE_TIME_FMT)},
71 {"$long_date", locale.GetInfo(wxLOCALE_LONG_DATE_FMT)},
72 {"$weekday_short_date_time", "%a " +
73 locale.GetInfo(wxLOCALE_SHORT_DATE_FMT) +
74 " " + locale.GetInfo(wxLOCALE_TIME_FMT)},
75 {"$weekday_short_date", "%a " + locale.GetInfo(wxLOCALE_SHORT_DATE_FMT)},
76 {"$short_date_time", locale.GetInfo(wxLOCALE_SHORT_DATE_FMT) + " " +
77 locale.GetInfo(wxLOCALE_TIME_FMT)},
78 {"$short_date", locale.GetInfo(wxLOCALE_SHORT_DATE_FMT)},
79 {"$hour_minutes_seconds", locale.GetInfo(wxLOCALE_TIME_FMT)},
80#else
81 {"$long_date_time", "%x %X"},
82 {"$long_date", "%x"}, // There is no descriptor for localized long date.
83 // Fallback to short date.
84 {"$weekday_short_date_time", "%a %x %X"},
85 {"$weekday_short_date", "%a %x"},
86 {"$short_date_time", "%x %X"},
87 {"$short_date", "%x"},
88 {"$hour_minutes_seconds", "%X"},
89#endif
90 {"$hour_minutes", "%H:%M"},
91 {"$24_hour_minutes_seconds", "%H:%M:%S"},
92 };
93 wxString format = options.format_string;
94 if (format == "") {
95 format = "$weekday_short_date_time";
96 }
97 // Iterate through the formatMap and replace each key with its value in
98 // the format string.
99 for (const auto& pair : formatMap) {
100 if (format.Contains(pair.first)) {
101 format.Replace(pair.first, pair.second);
102 }
103 }
104 // wxDateTime::Format() does not work when the format string contains 0x202F
105 // (narrow no-break space). Replace it with a regular space.
106 format.Replace(wxString(wxUniChar(0x202F)), " ");
107 wxString ret;
108 wxString tzName;
109 if (effective_time_zone == "Local Time") {
110 wxDateTime now = wxDateTime::Now();
111 if ((now == (now.ToGMT())) &&
112 t.IsDST()) // bug in wxWingets 3.0 for UTC meridien ?
113 t.Add(wxTimeSpan(1, 0, 0, 0));
114 if (options.show_timezone) {
115#ifdef __WXMSW__
116 tzName = _("LOC");
117#else
118 // Get the name of the timezone configured in the operating system.
119 // Formatting with the actual timezone (rather than "LOC") makes the
120 // labels unambiguous, even if the user changes the timezone settings in
121 // the operating system. For example "2021-10-31 01:30:00 EDT" is
122 // unambiguous, while "2021-10-31 01:30:00 LOC" is not.
123 tzName = t.Format("%Z");
124#endif
125 }
126 } else if (effective_time_zone == "LMT") {
127 // Local mean solar time at the current location.
128 t.MakeUTC();
129 tzName = _("LMT");
130 if (std::isnan(options.longitude)) {
131 t = wxInvalidDateTime;
132 } else {
133 t.Add(wxTimeSpan(0, 0, wxLongLong(options.longitude * 3600. / 15.)));
134 }
135 } else {
136 // UTC, or fallback to UTC if the timezone is not recognized.
137 t.MakeUTC();
138 tzName = _("UTC");
139 }
140 wxString formattedDate = t.Format(format);
141 if (options.show_timezone) {
142 return formattedDate + " " + tzName;
143 } else {
144 return formattedDate;
145 }
146}
147
148} // namespace ocpn
wxString g_datetime_format
Date/time format to use when formatting date/time strings.
Date and time utilities.
Standard, mostly strings utilities.
Definition datetime.cpp:39
wxString getUsrDateTimeFormat()
Return the date/time format to use when formatting date/time strings.
Definition datetime.cpp:41
PlugIn Object Definition/API.
Configuration options for date and time formatting.