utc.ToDateTimeUnsafe());
}
+ public static TheoryData<string, DateTimeUtc> Parse_Test_Fixtures = new TheoryData<string, DateTimeUtc>
+ {
+ { "2018-05-06T11:22:33.111", new DateTimeUtc(2018, 5, 6, 11, 22, 33, 111) },
+ { "2018-05-06T11:22:33.111+00:00", new DateTimeUtc(2018, 5, 6, 11, 22, 33, 111) },
+ { "2018-05-06T11:22:33.111+09:00", new DateTimeUtc(2018, 5, 6, 2, 22, 33, 111) },
+ };
+
+ [Theory]
+ [MemberData(nameof(Parse_Test_Fixtures))]
+ public void Parse_Test(string input, DateTimeUtc expected)
+ => Assert.Equal(expected, DateTimeUtc.Parse(input, DateTimeFormatInfo.InvariantInfo));
+
+ [Fact]
+ public void Parse_ErrorTest()
+ => Assert.Throws<FormatException>(() => DateTimeUtc.Parse("### INVALID ###", DateTimeFormatInfo.InvariantInfo));
+
public static TheoryData<string, bool, DateTimeUtc> TryParse_Test_Fixtures = new TheoryData<string, bool, DateTimeUtc>
{
{ "2018-05-06T11:22:33.111", true, new DateTimeUtc(2018, 5, 6, 11, 22, 33, 111) },
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
Nickname = "upsilon",
ScreenName = "kim_upsilon",
Text = "<a href=\"https://twitter.com/twitterapi\">@twitterapi</a> hogehoge",
- CreatedAt = new DateTime(2015, 3, 30, 3, 30, 0),
+ CreatedAt = new DateTimeUtc(2015, 3, 30, 3, 30, 0),
};
// PostClass.Text はリンクを除去するのみでエスケープは行わない
var expected = "<a class=\"quote-tweet-link\" href=\"//opentween/status/12345\">" +
"<blockquote class=\"quote-tweet\">" +
- "<p>@twitterapi hogehoge</p> — upsilon (@kim_upsilon) " + DateTime.Parse("2015/03/30 3:30:00") +
+ "<p>@twitterapi hogehoge</p> — upsilon (@kim_upsilon) " + DateTimeUtc.Parse("2015/03/30 3:30:00", DateTimeFormatInfo.InvariantInfo).ToLocalTimeString() +
"</blockquote></a>";
Assert.Equal(expected, TweetDetailsView.FormatQuoteTweetHtml(post, isReply: false));
}
public static DateTimeUtc FromUnixTime(long unixTime)
=> UnixEpoch + TimeSpan.FromTicks(unixTime * TimeSpan.TicksPerSecond);
+ public static DateTimeUtc Parse(string input, IFormatProvider formatProvider)
+ => new DateTimeUtc(DateTimeOffset.Parse(input, formatProvider, DateTimeStyles.AssumeUniversal));
+
public static bool TryParse(string input, IFormatProvider formatProvider, out DateTimeUtc result)
{
if (DateTimeOffset.TryParse(input, formatProvider, DateTimeStyles.AssumeUniversal, out var datetimeOffset))
public override void AddPostQueue(PostClass post)
{
base.AddPostQueue(post);
- this.UpdateTimelineSpeed(new DateTimeUtc(post.CreatedAt.ToUniversalTime()));
+ this.UpdateTimelineSpeed(post.CreatedAt);
}
public override async Task RefreshAsync(Twitter tw, bool backward, bool startup, IProgress<string> progress)
public string ImageUrl { get; set; }
public string ScreenName { get; set; }
- public DateTime CreatedAt { get; set; }
+ public DateTimeUtc CreatedAt { get; set; }
public long StatusId { get; set; }
private bool _IsFav;
var dateTimeFormat = settingCommon.DateTimeFormat;
try
{
- if (DateTime.Now.ToString(dateTimeFormat).Length == 0)
+ if (DateTimeUtc.Now.ToLocalTimeString(dateTimeFormat).Length == 0)
{
// このブロックは絶対に実行されないはず
// 変換が成功した場合にLengthが0にならない
{
try
{
- LabelDateTimeFormatApplied.Text = DateTime.Now.ToString(CmbDateTimeFormat.Text);
+ LabelDateTimeFormatApplied.Text = DateTimeUtc.Now.ToLocalTimeString(CmbDateTimeFormat.Text);
}
catch (FormatException)
{
string[] sitem= {"",
Post.Nickname,
Post.IsDeleted ? "(DELETED)" : Post.AccessibleText.Replace('\n', ' '),
- Post.CreatedAt.ToString(SettingManager.Common.DateTimeFormat),
+ Post.CreatedAt.ToLocalTimeString(SettingManager.Common.DateTimeFormat),
Post.ScreenName,
"",
mk.ToString(),
string[] sitem = {"",
Post.Nickname,
Post.IsDeleted ? "(DELETED)" : Post.AccessibleText.Replace('\n', ' '),
- Post.CreatedAt.ToString(SettingManager.Common.DateTimeFormat),
+ Post.CreatedAt.ToLocalTimeString(SettingManager.Common.DateTimeFormat),
Post.ScreenName + Environment.NewLine + "(RT:" + Post.RetweetedBy + ")",
"",
mk.ToString(),
if (post.IsProtect) protect = "Protect";
sw.WriteLine(post.Nickname + "\t" +
"\"" + post.TextFromApi.Replace("\n", "").Replace("\"", "\"\"") + "\"" + "\t" +
- post.CreatedAt + "\t" +
+ post.CreatedAt.ToLocalTimeString() + "\t" +
post.ScreenName + "\t" +
post.StatusId + "\t" +
post.ImageUrl + "\t" +
if (post.IsProtect) protect = "Protect";
sw.WriteLine(post.Nickname + "\t" +
"\"" + post.TextFromApi.Replace("\n", "").Replace("\"", "\"\"") + "\"" + "\t" +
- post.CreatedAt + "\t" +
+ post.CreatedAt.ToLocalTimeString() + "\t" +
post.ScreenName + "\t" +
post.StatusId + "\t" +
post.ImageUrl + "\t" +
if (_statuses.ContainsKey(_curPost.InReplyToStatusId.Value))
{
PostClass repPost = _statuses[_curPost.InReplyToStatusId.Value];
- MessageBox.Show($"{repPost.ScreenName} / {repPost.Nickname} ({repPost.CreatedAt})" + Environment.NewLine + repPost.TextFromApi);
+ MessageBox.Show($"{repPost.ScreenName} / {repPost.Nickname} ({repPost.CreatedAt.ToLocalTimeString()})" + Environment.NewLine + repPost.TextFromApi);
}
else
{
{
if (tb == null || !tb.Contains(_curPost.InReplyToStatusId.Value)) break;
PostClass repPost = _statuses[_curPost.InReplyToStatusId.Value];
- MessageBox.Show($"{repPost.ScreenName} / {repPost.Nickname} ({repPost.CreatedAt})" + Environment.NewLine + repPost.TextFromApi);
+ MessageBox.Show($"{repPost.ScreenName} / {repPost.Nickname} ({repPost.CreatedAt.ToLocalTimeString()})" + Environment.NewLine + repPost.TextFromApi);
return;
}
await this.OpenUriInBrowserAsync(MyCommon.GetStatusUrl(_curPost.InReplyToUser, _curPost.InReplyToStatusId.Value));
loadTasks.Add(this.SetUserPictureAsync(post.ImageUrl));
- DateTimeLabel.Text = post.CreatedAt.ToString();
+ DateTimeLabel.Text = post.CreatedAt.ToLocalTimeString();
}
if (this.DumpPostClass)
sb.AppendFormat("NickName : {0}<br>", post.Nickname);
sb.AppendFormat("Text : {0}<br>", post.Text);
sb.AppendFormat("(PlainText) : <xmp>{0}</xmp><br>", post.Text);
- sb.AppendFormat("CreatedAt : {0}<br>", post.CreatedAt);
+ sb.AppendFormat("CreatedAt : {0}<br>", post.CreatedAt.ToLocalTimeString());
sb.AppendFormat("Source : {0}<br>", post.Source);
sb.AppendFormat("UserId : {0}<br>", post.UserId);
sb.AppendFormat("FilterHit : {0}<br>", post.FilterHit);
var innerHtml = "<p>" + StripLinkTagHtml(post.Text) + "</p>" +
" — " + WebUtility.HtmlEncode(post.Nickname) +
" (@" + WebUtility.HtmlEncode(post.ScreenName) + ") " +
- WebUtility.HtmlEncode(post.CreatedAt.ToString());
+ WebUtility.HtmlEncode(post.CreatedAt.ToLocalTimeString());
return FormatQuoteTweetHtml(post.StatusId, innerHtml, isReply);
}
{
var retweeted = status.RetweetedStatus;
- post.CreatedAt = MyCommon.DateTimeParse(retweeted.CreatedAt);
+ post.CreatedAt = new DateTimeUtc(MyCommon.DateTimeParse(retweeted.CreatedAt).ToUniversalTime());
//Id
post.RetweetedId = retweeted.Id;
}
else
{
- post.CreatedAt = MyCommon.DateTimeParse(status.CreatedAt);
+ post.CreatedAt = new DateTimeUtc(MyCommon.DateTimeParse(status.CreatedAt).ToUniversalTime());
//本文
post.TextFromApi = status.FullText;
entities = status.MergedEntities;
}
//sender_id
//recipient_id
- post.CreatedAt = MyCommon.DateTimeParse(message.CreatedAt);
+ post.CreatedAt = new DateTimeUtc(MyCommon.DateTimeParse(message.CreatedAt).ToUniversalTime());
//本文
var textFromApi = message.Text;
//HTMLに整形