2 * PROJECT: ReactOS system libraries
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Japanese era support
5 * COPYRIGHT: Copyright 2019 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
13 #define JAPANESE_ERA_MAX 16
15 /* #define DONT_USE_REGISTRY */
17 static DWORD s_JapaneseEraCount
= 0;
18 static JAPANESE_ERA s_JapaneseEraTable
[JAPANESE_ERA_MAX
]
19 #ifdef DONT_USE_REGISTRY
22 {1868, 1, 1, {0x660E, 0x6CBB}, {0x660E, 0}, L
"Meiji", L
"M"},
23 {1912, 7, 30, {0x5927, 0x6B63}, {0x5927, 0}, L
"Taisho", L
"T"},
24 {1926, 12, 25, {0x662D, 0x548C}, {0x662D, 0}, L
"Showa", L
"S"},
25 {1989, 1, 8, {0x5E73, 0x6210}, {0x5E73, 0}, L
"Heisei", L
"H"},
26 {2019, 5, 1, {0x4EE4, 0x548C}, {0x4EE4, 0}, L
"Reiwa", L
"R"},
31 HANDLE
NLS_RegOpenKey(HANDLE hRootKey
, LPCWSTR szKeyName
);
33 BOOL
NLS_RegEnumValue(HANDLE hKey
, UINT ulIndex
,
34 LPWSTR szValueName
, ULONG valueNameSize
,
35 LPWSTR szValueData
, ULONG valueDataSize
);
37 static INT
JapaneseEra_Compare(const void *e1
, const void *e2
)
39 PCJAPANESE_ERA pEra1
= (PCJAPANESE_ERA
)e1
;
40 PCJAPANESE_ERA pEra2
= (PCJAPANESE_ERA
)e2
;
41 if (pEra1
->wYear
< pEra2
->wYear
)
43 if (pEra1
->wYear
> pEra2
->wYear
)
45 if (pEra1
->wMonth
< pEra2
->wMonth
)
47 if (pEra1
->wMonth
> pEra2
->wMonth
)
49 if (pEra1
->wDay
< pEra2
->wDay
)
51 if (pEra1
->wDay
> pEra2
->wDay
)
58 * https://en.wikipedia.org/wiki/Japanese_era_name
59 * https://docs.microsoft.com/en-us/windows/desktop/Intl/era-handling-for-the-japanese-calendar
61 static PCJAPANESE_ERA
JapaneseEra_Load(DWORD
*pdwCount
)
63 #ifndef DONT_USE_REGISTRY
64 HANDLE KeyHandle
= NULL
;
66 WCHAR szName
[128], szValue
[128];
68 LPWSTR pch1
, pch2
, pch3
, pch4
;
71 ASSERT(pdwCount
!= NULL
);
73 /* return cache if any */
74 if (s_JapaneseEraCount
!= 0)
76 *pdwCount
= s_JapaneseEraCount
;
77 return s_JapaneseEraTable
;
80 #ifdef DONT_USE_REGISTRY
81 s_JapaneseEraCount
= ARRAYSIZE(s_JapaneseEraTable
);
85 RtlZeroMemory(&s_JapaneseEraTable
, sizeof(s_JapaneseEraTable
));
87 /* open registry key */
88 KeyHandle
= NLS_RegOpenKey(NULL
, L
"\\Registry\\Machine\\System\\"
89 L
"CurrentControlSet\\Control\\Nls\\Calendars\\Japanese\\Eras");
94 for (dwIndex
= 0; dwIndex
< JAPANESE_ERA_MAX
; ++dwIndex
)
96 pEntry
= &s_JapaneseEraTable
[dwIndex
];
98 /* get name and data */
99 if (!NLS_RegEnumValue(KeyHandle
, dwIndex
, szName
, sizeof(szName
),
100 szValue
, sizeof(szValue
)))
107 pch2
= wcschr(pch1
, L
' ');
112 *pch2
++ = UNICODE_NULL
;
114 pch3
= wcschr(pch2
, L
' ');
119 *pch3
++ = UNICODE_NULL
;
121 pEntry
->wYear
= _wtoi(pch1
);
122 pEntry
->wMonth
= _wtoi(pch2
);
123 pEntry
->wDay
= _wtoi(pch3
);
124 if (pEntry
->wYear
== 0 || pEntry
->wMonth
== 0 || pEntry
->wDay
== 0)
131 pch2
= wcschr(pch1
, L
'_');
136 *pch2
++ = UNICODE_NULL
;
138 pch3
= wcschr(pch2
, L
'_');
143 *pch3
++ = UNICODE_NULL
;
145 pch4
= wcschr(pch3
, L
'_');
150 *pch4
++ = UNICODE_NULL
;
153 RtlStringCbCopyW(pEntry
->szEraName
, sizeof(pEntry
->szEraName
), pch1
);
154 RtlStringCbCopyW(pEntry
->szEraAbbrev
, sizeof(pEntry
->szEraAbbrev
), pch2
);
155 RtlStringCbCopyW(pEntry
->szEnglishEraName
, sizeof(pEntry
->szEnglishEraName
), pch3
);
156 RtlStringCbCopyW(pEntry
->szEnglishEraAbbrev
, sizeof(pEntry
->szEnglishEraAbbrev
), pch4
);
163 qsort(s_JapaneseEraTable
, s_JapaneseEraCount
, sizeof(JAPANESE_ERA
),
164 JapaneseEra_Compare
);
167 s_JapaneseEraCount
= dwIndex
;
170 *pdwCount
= s_JapaneseEraCount
;
172 return s_JapaneseEraTable
;
175 static BOOL
JapaneseEra_ToSystemTime(PCJAPANESE_ERA pEra
, LPSYSTEMTIME pst
)
177 ASSERT(pEra
!= NULL
);
180 ZeroMemory(pst
, sizeof(*pst
));
181 pst
->wYear
= pEra
->wYear
;
182 pst
->wMonth
= pEra
->wMonth
;
183 pst
->wDay
= pEra
->wDay
;
187 PCJAPANESE_ERA
JapaneseEra_Find(const SYSTEMTIME
*pst OPTIONAL
)
189 DWORD dwIndex
, dwCount
= 0;
190 PCJAPANESE_ERA pTable
, pEntry
, pPrevEntry
= NULL
;
201 SystemTimeToFileTime(pst
, &ft1
);
204 pTable
= JapaneseEra_Load(&dwCount
);
205 if (pTable
== NULL
|| dwCount
== 0 || dwCount
> JAPANESE_ERA_MAX
)
211 for (dwIndex
= 0; dwIndex
< dwCount
; dwIndex
++)
213 pEntry
= &pTable
[dwIndex
];
215 /* pEntry --> st2 --> ft2 */
216 JapaneseEra_ToSystemTime(pEntry
, &st2
);
217 SystemTimeToFileTime(&st2
, &ft2
);
220 nCompare
= CompareFileTime(&ft1
, &ft2
);