diff --git a/server/AyaNova/DataList/DataListSqlFilterCriteriaBuilder.cs b/server/AyaNova/DataList/DataListSqlFilterCriteriaBuilder.cs index 683d24c1..5977e339 100644 --- a/server/AyaNova/DataList/DataListSqlFilterCriteriaBuilder.cs +++ b/server/AyaNova/DataList/DataListSqlFilterCriteriaBuilder.cs @@ -792,22 +792,35 @@ namespace AyaNova.DataList //dates come in iso8601 UTC format from the client //suitable for the database to handle as all database dates are in UTC //Local display and parsing will be considered a CLIENT issue at all times - //so a simple parse should be sufficient - //https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings#Roundtrip - System.DateTime dtData = DateTime.Parse(sValue); - //THis is because we don't want milliseconds to alter the value in any way, AyaNova resolution for time is seconds not milliseconds to allow for some sloppiness + + //bugbug: comes with z at end indicating UTC so converts to local here, sb sticking to UTC, the z must be messing it up + //System.DateTime dtData = DateTime.Parse(sValue); + + //date comes to use as a string in iso8601 format including the "z" at the end + //parse needs to work exactly with it and not attempt to convert it to local time + + + // System.DateTime dtData = DateTime.ParseExact(sValue, "O", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind); + //Error=>System.FormatException: String '2021-02-05T17:40:35.094Z' was not recognized as a valid DateTime. + + System.DateTime dtData = DateTime.Parse(sValue).ToUniversalTime();//comes in UTC, parse converts it to local but touniversal puts it back in utc, weird but only thing that consistently work + + //THis is because we don't want milliseconds (or seconds in some cases) + //to alter the value in any way, AyaNova resolution for time is seconds not milliseconds to allow for some sloppiness + //and After Time values should start at zero seconds to encompass that minute because users can't select seconds in the UI when filtering etc //so no date is exact and we work around that with ranges that rule out milliseconds affecting query //also this needs to work in conjunction with client filters for date ranges that provide a value one second before the range in question as START timestamp //and exactly the end of range in question as END timestamp string sDateValueWithMaxMilliseconds = PostgresDateFormat(MaxMilliseconds(dtData)); string sDateValueWithZeroMilliseconds = PostgresDateFormat(ZeroMilliseconds(dtData)); + string sDateValueWithZeroSeconds = PostgresDateFormat(ZeroSeconds(dtData)); switch (sOperator) { case DataListFilterComparisonOperator.Equality: sb.Append(">='"); - sb.Append(sDateValueWithZeroMilliseconds); + sb.Append(sDateValueWithZeroSeconds); sb.Append("' AND "); sb.Append(SqlColumnNameToFilter); sb.Append(" "); @@ -976,7 +989,7 @@ namespace AyaNova.DataList //so nothing required there private static void BuildSQLBetweenTwoTokenDerivedDates(string sColumn, StringBuilder sb, DateTime dtAfter, DateTime dtBefore) { - + sb.Append(">'"); sb.Append(PostgresDateFormat(MaxMilliseconds(dtAfter.ToUniversalTime()))); sb.Append("' AND "); @@ -988,6 +1001,12 @@ namespace AyaNova.DataList } + private static DateTime ZeroSeconds(DateTime d) + { + if (d.Millisecond == 0) return d; + return new DateTime(d.Year, d.Month, d.Day, d.Hour, d.Minute, 0, DateTimeKind.Utc); + } + private static DateTime ZeroMilliseconds(DateTime d) { if (d.Millisecond == 0) return d; @@ -1005,7 +1024,7 @@ namespace AyaNova.DataList /// /// private static string PostgresDateFormat(DateTime theDate) - { + { //If this was used it should be like this for a UTC date to iso8601 // ISO8601 with 7 decimal places