Fixed: (DateTimeUtil) Check first for Standard Format in ParseDateTimeGoLang

This commit is contained in:
Bogdan
2023-02-25 22:41:32 +02:00
parent 09e40e0060
commit 201bc1944b
5 changed files with 99 additions and 86 deletions

View File

@@ -0,0 +1,43 @@
using System;
using System.Globalization;
using System.Threading;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.ParserTests
{
[TestFixture]
public class DateTimeUtilFixture : CoreTest
{
[TestCase("pt-BR")]
[TestCase("en-US")]
public void should_format_date_invariant(string culture)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
var dateNow = DateTime.Now;
DateTimeUtil.FromUnknown(dateNow.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture))
.ToString(DateTimeUtil.Rfc1123ZPattern, CultureInfo.InvariantCulture)
.Should().Be(dateNow.ToString("ddd, dd MMM yyyy HH':'mm':'ss z", CultureInfo.InvariantCulture));
}
[TestCase("2022-08-08 02:07:39 -02:00", "2006-01-02 15:04:05 -07:00", "yyyy-MM-dd HH:mm:ss zzz", "2022-08-08 04:07:39 +00:00")]
[TestCase("2022-08-08 02:07:39 -02:00", "yyyy-MM-dd HH:mm:ss zzz", "yyyy-MM-dd HH:mm:ss zzz", "2022-08-08 04:07:39 +00:00")]
[TestCase("2022-08-08 -02:00", "2006-01-02 -07:00", "yyyy-MM-dd zzz", "2022-08-08 +00:00")]
[TestCase("2022-08-08 -02:00", "yyyy-MM-dd zzz", "yyyy-MM-dd zzz", "2022-08-08 +00:00")]
[TestCase("02:07:39 -02:00", "15:04:05 -07:00", "HH:mm:ss zzz", "04:07:39 +00:00")]
[TestCase("02:07:39 -02:00", "HH:mm:ss zzz", "HH:mm:ss zzz", "04:07:39 +00:00")]
[TestCase("-02:00", "zzz", "zzz", "+00:00")]
[TestCase("-02:00", "-07:00", "zzz", "+00:00")]
public void parse_datetime_golang(string dateInput, string format, string standardFormat, string expectedDate)
{
DateTimeUtil.ParseDateTimeGoLang(dateInput, format)
.ToUniversalTime()
.ToString(standardFormat, CultureInfo.InvariantCulture)
.Should().Be(expectedDate);
}
}
}

View File

@@ -1,27 +0,0 @@
using System;
using System.Globalization;
using System.Threading;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Parser;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.ParserTests
{
[TestFixture]
public class DateUtilFixture : CoreTest
{
[TestCase("pt-BR")]
[TestCase("en-US")]
public void should_format_date_invariant(string culture)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
var dateNow = DateTime.Now;
DateTimeUtil.FromUnknown(dateNow.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture))
.ToString(DateTimeUtil.Rfc1123ZPattern, CultureInfo.InvariantCulture)
.Should().Be(dateNow.ToString("ddd, dd MMM yyyy HH':'mm':'ss z", CultureInfo.InvariantCulture));
}
}
}

View File

@@ -615,12 +615,6 @@ namespace NzbDrone.Core.Indexers.Cardigann
case "dateparse": case "dateparse":
var layout = (string)filter.Args; var layout = (string)filter.Args;
if (layout.Contains("yy") && DateTime.TryParseExact(data, layout, CultureInfo.InvariantCulture, DateTimeStyles.None, out var parsedDate))
{
data = parsedDate.ToString(DateTimeUtil.Rfc1123ZPattern, CultureInfo.InvariantCulture);
}
else
{
try try
{ {
var date = DateTimeUtil.ParseDateTimeGoLang(data, layout); var date = DateTimeUtil.ParseDateTimeGoLang(data, layout);
@@ -630,7 +624,6 @@ namespace NzbDrone.Core.Indexers.Cardigann
{ {
_logger.Debug(ex.Message); _logger.Debug(ex.Message);
} }
}
break; break;
case "regexp": case "regexp":

View File

@@ -509,7 +509,7 @@ namespace NzbDrone.Core.Indexers.Cardigann
value = release.Seeders.ToString(); value = release.Seeders.ToString();
break; break;
case "date": case "date":
release.PublishDate = DateTimeUtil.FromUnknown(value); release.PublishDate = DateTime.TryParseExact(value, DateTimeUtil.Rfc1123ZPattern, CultureInfo.InvariantCulture, DateTimeStyles.None, out var parsedDate) ? parsedDate : DateTimeUtil.FromUnknown(value);
value = release.PublishDate.ToString(DateTimeUtil.Rfc1123ZPattern, CultureInfo.InvariantCulture); value = release.PublishDate.ToString(DateTimeUtil.Rfc1123ZPattern, CultureInfo.InvariantCulture);
break; break;
case "files": case "files":

View File

@@ -251,69 +251,73 @@ namespace NzbDrone.Core.Parser
public static DateTime ParseDateTimeGoLang(string date, string layout) public static DateTime ParseDateTimeGoLang(string date, string layout)
{ {
date = date.Trim(); date = date.Trim();
var pattern = layout;
var commonStandardFormats = new[] { "y", "h", "d" };
if (commonStandardFormats.Any(layout.ContainsIgnoreCase) && DateTime.TryParseExact(date, layout, CultureInfo.InvariantCulture, DateTimeStyles.None, out var parsedDate))
{
return parsedDate;
}
var format = layout
// year // year
pattern = pattern.Replace("2006", "yyyy"); .Replace("2006", "yyyy")
pattern = pattern.Replace("06", "yy"); .Replace("06", "yy")
// month // month
pattern = pattern.Replace("January", "MMMM"); .Replace("January", "MMMM")
pattern = pattern.Replace("Jan", "MMM"); .Replace("Jan", "MMM")
pattern = pattern.Replace("01", "MM"); .Replace("01", "MM")
// day // day
pattern = pattern.Replace("Monday", "dddd"); .Replace("Monday", "dddd")
pattern = pattern.Replace("Mon", "ddd"); .Replace("Mon", "ddd")
pattern = pattern.Replace("02", "dd"); .Replace("02", "dd")
pattern = pattern.Replace("2", "d"); .Replace("2", "d")
// hours/minutes/seconds // hours/minutes/seconds
pattern = pattern.Replace("05", "ss"); .Replace("05", "ss")
.Replace("15", "HH")
pattern = pattern.Replace("15", "HH"); .Replace("03", "hh")
pattern = pattern.Replace("03", "hh"); .Replace("3", "h")
pattern = pattern.Replace("3", "h"); .Replace("04", "mm")
.Replace("4", "m")
pattern = pattern.Replace("04", "mm"); .Replace("5", "s")
pattern = pattern.Replace("4", "m");
pattern = pattern.Replace("5", "s");
// month again // month again
pattern = pattern.Replace("1", "M"); .Replace("1", "M")
// fractional seconds // fractional seconds
pattern = pattern.Replace(".0000", "ffff"); .Replace(".0000", "ffff")
pattern = pattern.Replace(".000", "fff"); .Replace(".000", "fff")
pattern = pattern.Replace(".00", "ff"); .Replace(".00", "ff")
pattern = pattern.Replace(".0", "f"); .Replace(".0", "f")
.Replace(".9999", "FFFF")
pattern = pattern.Replace(".9999", "FFFF"); .Replace(".999", "FFF")
pattern = pattern.Replace(".999", "FFF"); .Replace(".99", "FF")
pattern = pattern.Replace(".99", "FF"); .Replace(".9", "F")
pattern = pattern.Replace(".9", "F");
// AM/PM // AM/PM
pattern = pattern.Replace("PM", "tt"); .Replace("PM", "tt")
pattern = pattern.Replace("pm", "tt"); // not sure if this works .Replace("pm", "tt") // not sure if this works
// timezones // timezones
// these might need further tuning // these might need further tuning
pattern = pattern.Replace("Z07:00", "'Z'zzz"); .Replace("Z07:00", "'Z'zzz")
pattern = pattern.Replace("Z07", "'Z'zz"); .Replace("Z07", "'Z'zz")
pattern = pattern.Replace("Z07:00", "'Z'zzz"); .Replace("Z07:00", "'Z'zzz")
pattern = pattern.Replace("Z07", "'Z'zz"); .Replace("Z07", "'Z'zz")
pattern = pattern.Replace("-07:00", "zzz"); .Replace("-07:00", "zzz")
pattern = pattern.Replace("-07", "zz"); .Replace("-07", "zz");
try try
{ {
return DateTime.ParseExact(date, pattern, CultureInfo.InvariantCulture); return DateTime.ParseExact(date, format, CultureInfo.InvariantCulture);
} }
catch (FormatException ex) catch (FormatException ex)
{ {
throw new InvalidDateException($"Error while parsing DateTime \"{date}\", using layout \"{layout}\" ({pattern}): {ex.Message}", ex); throw new InvalidDateException($"Error while parsing DateTime \"{date}\", using layout \"{layout}\" ({format}): {ex.Message}", ex);
} }
} }