OSDN Git Service

PostMultipartRequestクラスを追加
[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 #nullable enable
23
24 using System;
25 using System.Globalization;
26
27 namespace OpenTween
28 {
29     /// <summary>
30     /// <see cref="DateTimeKind.Utc"/> に固定された <see cref="DateTime"/> を扱うための構造体
31     /// </summary>
32     public readonly struct DateTimeUtc : IComparable<DateTimeUtc>, IEquatable<DateTimeUtc>
33     {
34         public static DateTimeUtc MinValue { get; }
35             = new DateTimeUtc(DateTime.SpecifyKind(DateTime.MinValue, DateTimeKind.Utc));
36
37         public static DateTimeUtc MaxValue { get; }
38             = new DateTimeUtc(DateTime.SpecifyKind(DateTime.MaxValue, DateTimeKind.Utc));
39
40         public static DateTimeUtc UnixEpoch { get; }
41             = new DateTimeUtc(1970, 1, 1, 0, 0, 0);
42
43         public static DateTimeUtc Now
44             => UseFakeNow ? FakeNow + FakeNowDrift : new DateTimeUtc(DateTime.UtcNow);
45
46         // テストコード用
47         internal static bool UseFakeNow = false;
48         internal static DateTimeUtc FakeNow = DateTimeUtc.MinValue;
49         internal static TimeSpan FakeNowDrift = TimeSpan.Zero;
50
51         private readonly DateTime datetime;
52
53         public DateTimeUtc(int year, int month, int day)
54             : this(year, month, day, hour: 0, minute: 0, second: 0)
55         {
56         }
57
58         public DateTimeUtc(int year, int month, int day, int hour, int minute, int second)
59             : this(year, month, day, hour, minute, second, millisecond: 0)
60         {
61         }
62
63         public DateTimeUtc(int year, int month, int day, int hour, int minute, int second, int millisecond)
64             : this(new DateTime(year, month, day, hour, minute, second, millisecond, DateTimeKind.Utc))
65         {
66         }
67
68         public DateTimeUtc(DateTimeOffset datetimeOffset)
69             : this(datetimeOffset.UtcDateTime)
70         {
71         }
72
73         public DateTimeUtc(long utcTicks)
74             : this(new DateTime(utcTicks, DateTimeKind.Utc))
75         {
76         }
77
78         public DateTimeUtc(DateTime datetime)
79         {
80             if (datetime.Kind != DateTimeKind.Utc)
81                 throw new ArgumentException("datetime には UTC に変換された時刻が必須です", nameof(datetime));
82
83             this.datetime = datetime;
84         }
85
86         public long UtcTicks
87             => this.datetime.Ticks;
88
89         public long ToUnixTime()
90             => (long)(this - UnixEpoch).TotalSeconds;
91
92         public DateTimeOffset ToDateTimeOffset()
93             => new(this.datetime);
94
95         public DateTimeOffset ToLocalTime()
96             => this.ToDateTimeOffset().ToLocalTime();
97
98         public DateTime ToDateTimeUnsafe()
99             => this.datetime;
100
101         public int CompareTo(DateTimeUtc other)
102             => this.datetime.CompareTo(other.datetime);
103
104         public bool Equals(DateTimeUtc other)
105             => this == other;
106
107         public override bool Equals(object obj)
108             => obj is DateTimeUtc other && this.Equals(other);
109
110         public override int GetHashCode()
111             => this.datetime.GetHashCode();
112
113         public override string ToString()
114             => this.ToString("G");
115
116         public string ToString(string format)
117             => this.ToDateTimeOffset().ToString(format);
118
119         public string ToLocalTimeString()
120             => this.ToLocalTimeString("G");
121
122         public string ToLocalTimeString(string format)
123             => this.ToLocalTime().ToString(format);
124
125         public static DateTimeUtc operator +(DateTimeUtc a, TimeSpan b)
126             => new(a.datetime + b);
127
128         public static DateTimeUtc operator -(DateTimeUtc a, TimeSpan b)
129             => new(a.datetime - b);
130
131         public static TimeSpan operator -(DateTimeUtc a, DateTimeUtc b)
132             => a.datetime - b.datetime;
133
134         public static bool operator ==(DateTimeUtc a, DateTimeUtc b)
135             => a.datetime == b.datetime;
136
137         public static bool operator !=(DateTimeUtc a, DateTimeUtc b)
138             => a.datetime != b.datetime;
139
140         public static bool operator <(DateTimeUtc a, DateTimeUtc b)
141             => a.datetime < b.datetime;
142
143         public static bool operator <=(DateTimeUtc a, DateTimeUtc b)
144             => a.datetime <= b.datetime;
145
146         public static bool operator >(DateTimeUtc a, DateTimeUtc b)
147             => a.datetime > b.datetime;
148
149         public static bool operator >=(DateTimeUtc a, DateTimeUtc b)
150             => a.datetime >= b.datetime;
151
152         public static DateTimeUtc FromUnixTime(long unixTime)
153             => UnixEpoch + TimeSpan.FromTicks(unixTime * TimeSpan.TicksPerSecond);
154
155         public static DateTimeUtc FromUnixTimeMilliseconds(long unixTimeMs)
156             => UnixEpoch + TimeSpan.FromTicks(unixTimeMs * TimeSpan.TicksPerMillisecond);
157
158         public static DateTimeUtc Parse(string input, IFormatProvider formatProvider)
159             => new(DateTimeOffset.Parse(input, formatProvider, DateTimeStyles.AssumeUniversal));
160
161         public static bool TryParse(string input, IFormatProvider formatProvider, out DateTimeUtc result)
162         {
163             if (DateTimeOffset.TryParse(input, formatProvider, DateTimeStyles.AssumeUniversal, out var datetimeOffset))
164             {
165                 result = new DateTimeUtc(datetimeOffset);
166                 return true;
167             }
168
169             result = MinValue;
170             return false;
171         }
172
173         public static bool TryParseExact(string input, string[] formats, IFormatProvider formatProvider, out DateTimeUtc result)
174         {
175             if (DateTimeOffset.TryParseExact(input, formats, formatProvider, DateTimeStyles.AssumeUniversal, out var datetimeOffset))
176             {
177                 result = new DateTimeUtc(datetimeOffset);
178                 return true;
179             }
180
181             result = MinValue;
182             return false;
183         }
184     }
185 }