OSDN Git Service

using var を使用する
[opentween/open-tween.git] / OpenTween / DateTimeUtc.cs
1 // OpenTween - Client of Twitter
2 // Copyright (c) 2018 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
3 // All rights reserved.
4 //
5 // This file is part of OpenTween.
6 //
7 // This program is free software; you can redistribute it and/or modify it
8 // under the terms of the GNU General Public License as published by the Free
9 // Software Foundation; either version 3 of the License, or (at your option)
10 // any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 // for more details.
16 //
17 // You should have received a copy of the GNU General Public License along
18 // with this program. If not, see <http://www.gnu.org/licenses/>, or write to
19 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20 // Boston, MA 02110-1301, USA.
21
22 using System;
23 using System.Globalization;
24
25 namespace OpenTween
26 {
27     /// <summary>
28     /// <see cref="DateTimeKind.Utc"/> に固定された <see cref="DateTime"/> を扱うための構造体
29     /// </summary>
30     public readonly struct DateTimeUtc : IComparable<DateTimeUtc>, IEquatable<DateTimeUtc>
31     {
32         public static DateTimeUtc MinValue { get; }
33             = new DateTimeUtc(DateTime.SpecifyKind(DateTime.MinValue, DateTimeKind.Utc));
34
35         public static DateTimeUtc MaxValue { get; }
36             = new DateTimeUtc(DateTime.SpecifyKind(DateTime.MaxValue, DateTimeKind.Utc));
37
38         public static DateTimeUtc UnixEpoch { get; }
39             = new DateTimeUtc(1970, 1, 1, 0, 0, 0);
40
41         public static DateTimeUtc Now
42             => new DateTimeUtc(DateTime.UtcNow);
43
44         private readonly DateTime datetime;
45
46         public DateTimeUtc(int year, int month, int day)
47             : this(year, month, day, hour: 0, minute: 0, second: 0)
48         {
49         }
50
51         public DateTimeUtc(int year, int month, int day, int hour, int minute, int second)
52             : this(year, month, day, hour, minute, second, millisecond: 0)
53         {
54         }
55
56         public DateTimeUtc(int year, int month, int day, int hour, int minute, int second, int millisecond)
57             : this(new DateTime(year, month, day, hour, minute, second, millisecond, DateTimeKind.Utc))
58         {
59         }
60
61         public DateTimeUtc(DateTimeOffset datetimeOffset)
62             : this(datetimeOffset.UtcDateTime)
63         {
64         }
65
66         public DateTimeUtc(long utcTicks)
67             : this(new DateTime(utcTicks, DateTimeKind.Utc))
68         {
69         }
70
71         public DateTimeUtc(DateTime datetime)
72         {
73             if (datetime.Kind != DateTimeKind.Utc)
74                 throw new ArgumentException("datetime には UTC に変換された時刻が必須です", nameof(datetime));
75
76             this.datetime = datetime;
77         }
78
79         public long UtcTicks
80             => this.datetime.Ticks;
81
82         public long ToUnixTime()
83             => (long)((this - UnixEpoch).TotalSeconds);
84
85         public DateTimeOffset ToDateTimeOffset()
86             => new DateTimeOffset(this.datetime);
87
88         public DateTimeOffset ToLocalTime()
89             => this.ToDateTimeOffset().ToLocalTime();
90
91         public DateTime ToDateTimeUnsafe()
92             => this.datetime;
93
94         public int CompareTo(DateTimeUtc other)
95             => this.datetime.CompareTo(other.datetime);
96
97         public bool Equals(DateTimeUtc other)
98             => this == other;
99
100         public override bool Equals(object obj)
101             => obj is DateTimeUtc other && this.Equals(other);
102
103         public override int GetHashCode()
104             => this.datetime.GetHashCode();
105
106         public override string ToString()
107             => this.ToString("G");
108
109         public string ToString(string format)
110             => this.ToDateTimeOffset().ToString(format);
111
112         public string ToLocalTimeString()
113             => this.ToLocalTimeString("G");
114
115         public string ToLocalTimeString(string format)
116             => this.ToLocalTime().ToString(format);
117
118         public static DateTimeUtc operator +(DateTimeUtc a, TimeSpan b)
119             => new DateTimeUtc(a.datetime + b);
120
121         public static DateTimeUtc operator -(DateTimeUtc a, TimeSpan b)
122             => new DateTimeUtc(a.datetime - b);
123
124         public static TimeSpan operator -(DateTimeUtc a, DateTimeUtc b)
125             => a.datetime - b.datetime;
126
127         public static bool operator ==(DateTimeUtc a, DateTimeUtc b)
128             => a.datetime == b.datetime;
129
130         public static bool operator !=(DateTimeUtc a, DateTimeUtc b)
131             => a.datetime != b.datetime;
132
133         public static bool operator <(DateTimeUtc a, DateTimeUtc b)
134             => a.datetime < b.datetime;
135
136         public static bool operator <=(DateTimeUtc a, DateTimeUtc b)
137             => a.datetime <= b.datetime;
138
139         public static bool operator >(DateTimeUtc a, DateTimeUtc b)
140             => a.datetime > b.datetime;
141
142         public static bool operator >=(DateTimeUtc a, DateTimeUtc b)
143             => a.datetime >= b.datetime;
144
145         public static DateTimeUtc FromUnixTime(long unixTime)
146             => UnixEpoch + TimeSpan.FromTicks(unixTime * TimeSpan.TicksPerSecond);
147
148         public static DateTimeUtc Parse(string input, IFormatProvider formatProvider)
149             => new DateTimeUtc(DateTimeOffset.Parse(input, formatProvider, DateTimeStyles.AssumeUniversal));
150
151         public static bool TryParse(string input, IFormatProvider formatProvider, out DateTimeUtc result)
152         {
153             if (DateTimeOffset.TryParse(input, formatProvider, DateTimeStyles.AssumeUniversal, out var datetimeOffset))
154             {
155                 result = new DateTimeUtc(datetimeOffset);
156                 return true;
157             }
158
159             result = MinValue;
160             return false;
161         }
162
163         public static bool TryParseExact(string input, string[] formats, IFormatProvider formatProvider, out DateTimeUtc result)
164         {
165             if (DateTimeOffset.TryParseExact(input, formats, formatProvider, DateTimeStyles.AssumeUniversal, out var datetimeOffset))
166             {
167                 result = new DateTimeUtc(datetimeOffset);
168                 return true;
169             }
170
171             result = MinValue;
172             return false;
173         }
174     }
175 }