1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     fnd_DateTime.h
4 
5   Copyright (C)2009 Nintendo Co., Ltd.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Rev: 28097 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NN_FND_DATETIME_API_H_
17 #define NN_FND_DATETIME_API_H_
18 
19 /*! @file
20 
21     :include nn/fnd.h
22 */
23 
24 #include <nn/types.h>
25 #include <nn/assert.h>
26 #include <nn/fnd/fnd_TimeSpan.h>
27 
28 #ifdef __cplusplus
29 
30 namespace nn {
31 namespace fnd {
32 
33 /*!
34     @brief  曜日を表す定数です。
35 */
36 enum Week
37 {
38     WEEK_SUNDAY = 0,   ///< 日曜日
39     WEEK_MONDAY,       ///< 月曜日
40     WEEK_TUESDAY,      ///< 火曜日
41     WEEK_WEDNESDAY,    ///< 水曜日
42     WEEK_THURSDAY,     ///< 木曜日
43     WEEK_FRIDAY,       ///< 金曜日
44     WEEK_SATURDAY,     ///< 土曜日
45     WEEK_MAX
46 };
47 
48 /*!
49     @brief  日時を表す構造体です。
50 */
51 struct DateTimeParameters
52 {
53     s32     year;         ///< 年
54     s8      month;        ///< 月
55     s8      day;          ///< 日
56     Week    week;         ///< 曜日
57     s8      hour;         ///< 時
58     s8      minute;       ///< 分
59     s8      second;       ///< 秒
60     s16     milliSecond;  ///< ミリ秒
61 };
62 
63 /*!
64     @brief  日時を表します。
65 
66     日時は、1900-01-01 00:00:00.000 から 2189-12-31 23:59:59.999 まで扱えます。
67 
68     2000-01-01(土) を基準として全ての年をグレゴリオ暦で計算しています。
69     1日は正確に86400秒であるとして日時を扱います。
70 
71     DateTime は @ref TimeSpan との加減算を提供しています。
72     DateTime と @ref TimeSpan との加減算により DateTime が得られます。
73     DateTime 同士の減算により @ref TimeSpan が得られます。
74     DateTimeの上限と下限は、DateTime 同士の減算で得られる TimeSpan がオーバーフローしないように設定されています。
75 
76 */
77 class DateTime
78 {
79 public:
80     /*!
81         :overload noparams
82 
83         @brief 2000-01-01 00:00:00.000 の DateTime オブジェクトを作ります。
84     */
DateTime()85     DateTime() : m_MilliSeconds(0) {}
86 
87     /*!
88         :overload withparams
89 
90         @brief 指定日時の DateTime オブジェクトを作ります。
91     */
92     DateTime(s32 year, s32 month, s32 day, s32 hour=0, s32 minute=0, s32 second=0, s32 millisecond=0);
93 
94     /*!
95         @brief 年を取得します。
96 
97         @return 4桁の西暦を返します。
98 
99         経過時間からの変換するための計算を含みます。
100     */
101     s32  GetYear() const;
102 
103     /*!
104         @brief 月を取得します。
105 
106         @return 月を 1 から 12 の値で返します。
107 
108         経過時間からの変換するための計算を含みます。
109     */
110     s32 GetMonth() const;
111 
112     /*!
113         @brief 日を取得します。
114 
115         @return 日を 1 から 31 の値で返します。
116 
117         経過時間からの変換するための計算を含みます。
118     */
119     s32 GetDay() const;
120 
121     /*!
122         @brief 曜日を取得します。
123 
124         @return 曜日を返します。
125 
126         経過時間からの変換するための計算を含みます。
127     */
128     Week GetWeek() const;
129 
130     /*!
131         @brief  時を取得します。
132 
133         @return 時を 0 から 23 の値で返します。
134 
135         経過時間からの変換するための計算を含みます。
136     */
137     s32 GetHour() const;
138 
139     /*!
140         @brief 分を取得します。
141 
142         @return 分を 0 から 59 の値で返します。
143 
144         経過時間からの変換するための計算を含みます。
145     */
146     s32 GetMinute() const;
147 
148     /*!
149         @brief 秒を取得します。
150 
151         @return 秒を 0 から 59 の値で返します。
152 
153         経過時間からの変換するための計算を含みます。
154     */
155     s32 GetSecond() const;
156 
157     /*!
158         @brief ミリ秒を取得します。
159 
160         @return ミリ秒を 0 から 999 の値で返します。
161 
162         経過時間からの変換するための計算を含みます。
163     */
164     s32 GetMilliSecond() const;
165 
166     /*!
167         @brief 年月日時分秒の値をまとめて取得します。
168 
169         @return @ref DateTimeParameters を返します。
170     */
171     DateTimeParameters GetParameters() const;
172 
173     /*!
174         @brief  年を置き換えます。
175         @return 置き換えられた DateTime オブジェクトを返します。
176     */
177     DateTime ReplaceYear(s32 year) const;
178 
179     /*!
180         @brief  月を置き換えます。
181         @return 置き換えられた DateTime オブジェクトを返します。
182     */
183     DateTime ReplaceMonth(s32 month) const;
184 
185     /*!
186         @brief  日を置き換えます。
187         @return 置き換えられた DateTime オブジェクトを返します。
188     */
189     DateTime ReplaceDay(s32 day) const;
190 
191     /*!
192         @brief  時を置き換えます。
193         @return 置き換えられた DateTime オブジェクトを返します。
194     */
195     DateTime ReplaceHour(s32 hour) const;
196 
197     /*!
198         @brief  分を置き換えます。
199         @return 置き換えられた DateTime オブジェクトを返します。
200     */
201     DateTime ReplaceMinute(s32 minute) const;
202 
203     /*!
204         @brief  秒を置き換えます。
205         @return 置き換えられた DateTime オブジェクトを返します。
206     */
207     DateTime ReplaceSecond(s32 second) const;
208 
209     /*!
210         @brief  ミリ秒を置き換えます。
211         @return 置き換えられた DateTime オブジェクトを返します。
212     */
213     DateTime ReplaceMilliSecond(s32 millisecond) const;
214 
215     /*!
216         @brief  DateTime 同士の == 演算です。
217     */
218     friend bool operator==(const DateTime& lhs, const DateTime& rhs) { return lhs.m_MilliSeconds == rhs.m_MilliSeconds; }
219 
220     /*!
221         @brief  DateTime 同士の != 演算です。
222     */
223     friend bool operator!=(const DateTime& lhs, const DateTime& rhs) { return !(lhs == rhs); }
224 
225     /*!
226         @brief  DateTime 同士の < 演算です。
227     */
228     friend bool operator< (const DateTime& lhs, const DateTime& rhs) { return lhs.m_MilliSeconds <  rhs.m_MilliSeconds; }
229 
230     /*!
231         @brief  DateTime 同士の > 演算です。
232     */
233     friend bool operator> (const DateTime& lhs, const DateTime& rhs) { return rhs < lhs; }
234 
235     /*!
236         @brief  DateTime 同士の <= 演算です。
237     */
238     friend bool operator<=(const DateTime& lhs, const DateTime& rhs) { return !(lhs > rhs); }
239 
240     /*!
241         @brief  DateTime 同士の >= 演算です。
242     */
243     friend bool operator>=(const DateTime& lhs, const DateTime& rhs) { return !(lhs < rhs); }
244 
245     /*!
246         @brief  DateTime と TimeSpan の += 演算です。
247     */
248     DateTime& operator+=(const TimeSpan& rhs) { this->m_MilliSeconds += rhs.GetMilliSeconds(); return *this; }
249 
250     /*!
251         @brief  DateTime と TimeSpan の + 演算です。
252     */
253     friend DateTime operator+(const DateTime& lhs, const TimeSpan& rhs) { DateTime ret(lhs); return ret += rhs; }
254 
255     /*!
256         @brief  DateTime と TimeSpan の -= 演算です。
257     */
258     DateTime& operator-=(const TimeSpan& rhs) { this->m_MilliSeconds -= rhs.GetMilliSeconds(); return *this; }
259 
260     /*!
261         @brief  DateTime と TimeSpan の - 演算です。
262     */
263     friend DateTime operator-(const DateTime& lhs, const TimeSpan& rhs) { DateTime ret(lhs); return ret -= rhs; }
264 
265     /*!
266         @brief  DateTime 同士の - 演算です。
267 
268         MIN_DATETIME から MAX_DATETIME までの値で表される有効な DateTime 同士の減算の結果は、
269         TimeSpan で表現可能な範囲に収まります。
270 
271         @return 差の @ref TimeSpan を返します。
272     */
273     friend TimeSpan operator-(const DateTime& lhs, const DateTime& rhs) { return TimeSpan::FromMilliSeconds(lhs.m_MilliSeconds - rhs.m_MilliSeconds); }
274 
275     /*!
276         :overload   nostruct
277 
278         @brief 年月日時分秒から DateTime オブジェクトを作成します。
279 
280         暦として有効な日時を指定してください。
281         無効な日付を指定した結果は不定です。
282         指定する日時が有効かどうか調べるには、@ref IsValidParameters を使用できます。
283 
284         @param[in]  year        年を指定します。[ 1900 ... 2189]
285         @param[in]  month       月を指定します。[ 1 ... 12 ]
286         @param[in]  day         日を指定します。[ 1 ... 31 ]
287         @param[in]  hour        時を指定します。[ 0 ... 23 ]
288         @param[in]  minute      分を指定します。[ 0 ... 59 ]
289         @param[in]  second      秒を指定します。[ 0 ... 59 ]
290         @param[in]  millisecond ミリ秒を指定します。[ 0 ... 999 ]
291 
292         @return 指定日時の DateTime オブジェクトを返します。
293     */
294     static DateTime FromParameters(s32 year, s32 month, s32 day, s32 hour=0, s32 minute=0, s32 second=0, s32 millisecond=0);
295 
296     /*!
297         :overload withstruct
298 
299         @brief 年月日時分秒から DateTime オブジェクトを作成します。
300 
301         @ref DateTimeParameters での曜日の指定は無視されます。
302 
303         暦として有効な日時を指定してください。
304         無効な日付を指定した結果は不定です。
305         指定する日時が有効かどうか調べるには、@ref IsValidParameters を使用できます。
306 
307         @param[in]  dateTimeParameters  DateTimeParameters オブジェクトを指定します。
308 
309         @return 指定日時の DateTime オブジェクトを返します。
310     */
311     static DateTime FromParameters(const DateTimeParameters &dateTimeParameters);
312 
313     /*!
314         @brief 正しい日付か判定します。
315 
316         @param[in]  year    年を指定します。
317         @param[in]  month   月を指定します。
318         @param[in]  day     日を指定します。
319 
320         @return 正しい日付なら true を返し、不正な日付なら false を返します。
321     */
322     static bool IsValidDate(s32 year, s32 month, s32 day);
323 
324     /*!
325         :overload nostruct
326 
327         @brief 正しい日時か判定します。
328 
329         @param[in]  year        年を指定します。
330         @param[in]  month       月を指定します。
331         @param[in]  day         日を指定します。
332         @param[in]  hour        時を指定します。
333         @param[in]  minute      分を指定します。
334         @param[in]  second      秒を指定します。
335         @param[in]  millisecond ミリ秒を指定します。
336 
337         @return 正しい日時なら true を返し、不正な日時なら false を返します。
338     */
339     static bool IsValidParameters(s32 year, s32 month, s32 day, s32 hour=0, s32 minute=0, s32 second=0, s32 millisecond=0);
340 
341     /*!
342         :overload   withstruct
343 
344         @brief 正しい日時か判定します。
345 
346         @param[in]  dateTimeParameters  DateTimeParameters オブジェクトを指定します。
347 
348         @return 正しい日時なら true を返し、不正な日時なら false を返します。
349     */
350     static bool IsValidParameters(const DateTimeParameters &dateTimeParameters);
351 
352     /*!
353         @brief うるう年かどうか判定します。
354 
355         @param[in]  year    年を指定します。
356 
357         @return うるう年なら true を返し、平年なら false を返します。
358     */
359     static s32  IsLeapYear(s32 year);
360 
361     /*!
362         @brief 年月日から 2000-01-01 からの経過日数を計算します。
363 
364         @param[in]  year    年を指定します。
365         @param[in]  month   月を指定します。
366         @param[in]  day     日を指定します。
367 
368         @return 経過日数を返します。
369 
370         有効な日付を指定してください。
371         無効な日付を指定した結果は不定です。
372         指定する日付が有効かどうか調べるには、@ref IsValidDate を使用できます。
373     */
374     static s32  DateToDays(s32 year, s32 month, s32 day);
375 
376     /*!
377         @brief 2000-01-01 からの経過日数から年月日を計算します。
378 
379         @param[out] pYear   年を入れるアドレスを指定します。
380         @param[out] pMonth  月を入れるアドレスを指定します。
381         @param[out] pDay    日を入れるアドレスを指定します。
382         @param[in]  days    経過日数を指定します。
383     */
384     static void DaysToDate(s32 *pYear, s32 *pMonth, s32 *pDay, s32 days);
385 
386     /*!
387         @brief 2000-01-01 からの経過日数から曜日を計算します。
388 
389         @param[in]  days    経過日数を指定します。
390 
391         @return 曜日を返します。
392     */
393     static Week DaysToWeekday(s32 days);
394 
395     /*!
396         @brief 現在の日時を取得します。
397 
398         @return 現在の日時を返します。
399     */
400     static DateTime GetNow();
401 
402     /*!
403         @brief DateTimeで扱える最も過去の日時です。
404     */
405     static const DateTime MIN_DATETIME;
406 
407     /*!
408         @brief DateTimeで扱える最も未来の日時です。
409     */
410     static const DateTime MAX_DATETIME;
411 
412 private:
413     s64 m_MilliSeconds;
414 
DateTime(s64 milliseconds)415     DateTime(s64 milliseconds) : m_MilliSeconds(milliseconds) { NN_ASSERT(MIN_MILLISECONDS <= milliseconds && milliseconds <= MAX_MILLISECONDS); }
416 
417     static const s64 MIN_MILLISECONDS = -3155673600000LL;
418     static const s64 MAX_MILLISECONDS = 5995900800000LL - 1;
419 };
420 
421 } // namespace fnd {
422 } // namespace nn {
423 
424 #endif // #ifdef __cplusplus
425 
426 #endif //   #ifndef NN_FND_DATETIME_API_H_
427