Finding difference of 2 DateTime Objects with different timezones? - dart

I need to set the other object's timezone to match now object which has utc timezone.
I'm comparing two datetime objects but the 'difference' value does not match the expected value. Most likely down to the fact that both objects have different Time Zones (Utc & Bst).
void main() {
var now = new DateTime.now().toUtc();
print(now);
print(now.timeZoneName);
var other = DateTime.parse("2020-05-22 18:27:32.608069");
print(other);
print(other.timeZoneName);
var diff = now.difference(other);
print(diff);
}
output:
2020-05-22 19:26:39.169Z
UTC
2020-05-22 18:27:32.608
British Summer Time
1:59:06.561000

You don't want to convert, you want to read in a date/time as UTC.
Change
var other = DateTime.parse("2020-05-22 18:27:32.608069");
to
var other = DateTime.parse("2020-05-22 18:27:32.608069z");
If other is already constructed, you need to make a new object with DateTime.utc()
https://api.dart.dev/stable/2.8.2/dart-core/DateTime/DateTime.utc.html
var newDate = new DateTime.utc(other.year, other.month, other.day, other.hour, other.minute, other.second, other.millisecond, other.microsecond);

Related

Flutter/Dart DateTime parsing UTC and converting to local

I am trying to parse a UTC Date string to DateTime and then parse it to local, however I am having troubles with converting it to the local time. In the UK it should be plus one, however when I print .isUtc it returns as false.
This is what I have now:
print(widget.asset.purchaseDate);
DateTime temp = DateTime.parse(widget.asset.purchaseDate);
print(temp.toLocal());
I/flutter (5434): 2020-05-07 21:29:00
I/flutter (5434): 2020-05-07 21:29:00.000
You need to indicate a timezone to DateTime.parse, otherwise it assumes local time. From the dartdoc:
An optional time-zone offset part, possibly separated from the
previous by a space. The time zone is either 'z' or 'Z', or it is a
signed two digit hour part and an optional two digit minute part.
Since you know your string represents UTC, you can tell the parser by adding the Z suffix.
var temp = DateTime.parse(widget.asset.purchaseDate + 'Z');
print(temp.isUtc); // prints true
While #Richard Heap's answer stands I'd like DateTime.parseUtc() to exist.
If there will be a day when dart allows static extension methods here is an implementation that would work:
extension DateTimeExtension on DateTime {
static DateTime parseUtc(String formattedDate) => DateTime.parse('${formattedDate}z');
static DateTime? tryParseUtc(String? formattedDate) {
if (formattedDate != null) {
return DateTime.tryParse('${formattedDate}z');
}
return null;
}
}
Currently you'd have to use it with the extension classes name, like so:
DateTimeExtension.parseUtc(someDate)
or
DateTimeExtension.tryParseUtc(someOtherDate)
I think the latter is more useful where someOtherDate is nullable

Created Google Sheet Timezone

I have a script that converts and Excel file to a Google Sheet. However, the newly created Google Sheet defaults to the Pacific timezone. We already have our Company set to Eastern timezone in Google Admin. I also have the local machine that is executing the script set to Eastern timezone and the user is also set to Eastern timezone. The script project is set to Eastern timezone as well. If I goto Google Apps and create a sheet from scratch, it defaults to Eastern timezone as desired. But when the script creates the new sheet, it always defaults to Pacific timezone. Since it seems there's no way to set the timezone via a script function, is there anyway to make it default to Eastern timezone? Note as well that here in the Eastern timezone, we have the stupid daylight savings time. So it changes between -4 and -5, which is such a pain!
My reason for this is that after I convert the Excel to Google Sheet, I have to import the records into another import sheet. The imported data has dates and times that keep getting sku'd after or during the import. Since I import using the getRange.getValues function, it always performs the new Date(). I have tried the Utilities.format function as well. But I don't know if I can be sure that the timezone will stay the same. And since I can't read what timezone the created sheet has, it becomes a gamble.
I would appreciate any help that could be offered in the way of scripting fixes. It is not feasible for me to have to go in each time and change the timezone manually within the sheet itself.
Thanks for any help!
Doug
The conversion code:
function convertExceltoGoogleSheet(fileName, newFileName) {
try {
var fileName = fileName || "microsoft-excel.xlsx";
var excelFile = DriveApp.getFilesByName(fileName).next();
var fileId = excelFile.getId();
var folderId = Drive.Files.get(fileId).parents[0].id;
var blob = excelFile.getBlob();
//If no newFileName passed, create one
if (newFileName.trim() == '') {
//Generate formatted filename
var dateInfo = getDateInfo(-20);
var mo = dateInfo[2].toString();
if (mo.length < 2) {
var mo = "0" + mo;
}
var newFileName = dateInfo[0].toString() + "-" + mo + "-" + filename;
}
var resource = {
//title: excelFile.getName().replace(/.xlsx?/, ""), //use original filename
title: newFileName, //Use formatted filename from above
key: fileId,
parents: [{"id": folderId}]
};
var newFile = Drive.Files.insert(resource, blob, {
convert: true
});
return newFile.id;
} catch (f) {
Logger.log(f.toString());
}
}

unable to convert string date in Format yyyyMMddHHmmss to DateTime dart

i have a string containing date in format yyyyMMddHHmmss (e.g.) (20180626170555) and i am using following code to convert it into date time
dateTimeFromString(json['dateTime'], "yyyyMMddHHmmss")
exception is:
FormatException: Trying to read MM from 20180623130424 at position 14
what can be the reason?
DateTime.parse("string date here") accept some formatted string only. Check below examples of accepted strings.
"2012-02-27 13:27:00"
"2012-02-27 13:27:00.123456789z"
"2012-02-27 13:27:00,123456789z"
"20120227 13:27:00"
"20120227T132700"
"20120227"
"+20120227"
"2012-02-27T14Z"
"2012-02-27T14+00:00"
"-123450101 00:00:00 Z": in the year -12345.
"2002-02-27T14:00:00-0500": Same as "2002-02-27T19:00:00Z"
=> String to DateTime
DateTime tempDate = new DateFormat("yyyy-MM-dd hh:mm:ss").parse(savedDateString);
=> DateTime to String
String date = DateFormat("yyyy-MM-dd hh:mm:ss").format(DateTime.now());
Reference links:
Use intl for DateFormat from flutter package (https://pub.dev/packages/intl)
DateTime.parse() => https://api.dart.dev/stable/2.7.2/dart-core/DateTime/parse.html
intl DateFormat can't cope with your input string as it doesn't have any separators. The whole string gets consumed as the year. However DateTime.parse does cope with this (nearly). It happens to expect precisely the format you have (again, nearly).
One of the acceptable styles to parse is 20120227T132700, which just differs by the T date/time separator.
Try this:
String date = '20180626170555';
String dateWithT = date.substring(0, 8) + 'T' + date.substring(8);
DateTime dateTime = DateTime.parse(dateWithT);
to convert from "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" to 'MM/dd/yyyy hh:mm a'
date = '2021-01-26T03:17:00.000000Z';
DateTime parseDate =
new DateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse(date);
var inputDate = DateTime.parse(parseDate.toString());
var outputFormat = DateFormat('MM/dd/yyyy hh:mm a');
var outputDate = outputFormat.format(inputDate);
print(outputDate)
output
01/26/2021 03:17 AM
You can use DateFormat to parse a DateTime from string to an object
// With en_US locale by default
var newDateTimeObj = new DateFormat().add_yMd().add_Hms().parse("7/10/1996 10:07:23")
// with a defined format
var newDateTimeObj2 = new DateFormat("dd/MM/yyyy HH:mm:ss").parse("10/02/2000 15:13:09")
Check the doc here.
The Easient way convert a string into Date format is
print(DateTime.parse('2020-01-02')); // 2020-01-02 00:00:00.000
print(DateTime.parse('20200102')); // 2020-01-02 00:00:00.000
print(DateTime.parse('-12345-03-04')); // -12345-03-04 00:00:00.000
print(DateTime.parse('2020-01-02 07')); // 2020-01-02 07:00:00.000
print(DateTime.parse('2020-01-02T07')); // 2020-01-02 07:00:00.000
print(DateTime.parse('2020-01-02T07:12')); // 2020-01-02 07:12:00.000
print(DateTime.parse('2020-01-02T07:12:50')); // 2020-01-02 07:12:50.000
print(DateTime.parse('2020-01-02T07:12:50Z')); // 2020-01-02 07:12:50.000Z
print(DateTime.parse('2020-01-02T07:12:50+07')); // 2020-01-02 00:12:50.000Z
print(DateTime.parse('2020-01-02T07:12:50+0700')); // 2020-01-02 00:12:50.00
print(DateTime.parse('2020-01-02T07:12:50+07:00')); // 2020-01-02 00:12:50.00
From the docs, you need Single M to month in year :
dateTimeFromString(json['dateTime'], "yMdHms")
Basic information about how to convert String to Date and Date to string in flutter. Look at below link
https://quickstartflutterdart.blogspot.com/2018/10/how-to-convert-string-to-date-and-date.html
Might be it will be helped for others.
i did something like this (using the intl package)
final date = '7/10/1996';
final month = DateFormat.LLLL().format(DateTime.parse(date));
LLLL in the code above is date format skeleton meaning 'stand alone month', other date formatter is presented here
add String date as a parameter
DateTime.prase(String userString);
If you have a date and time string in a specific format, you can convert it to a DateTime object by using the parse() method. For example, if you have a string that contains “12/03/2019 9:45 AM”, you can use the parse() method to convert it to a DateTime object like this:
var dateTimeString = “12/03/2019 9:45 AM”;
var dateTimeObject = DateTime.parse(dateTimeString);
print(dateTimeObject); // 12/03/2019 09:45:00.000
The parse() method is very versatile and can handle a variety of different formats. If your string doesn’t follow a strict format, you can use tryParse() instead. This method will return null if it fails to parse the string.
for detail click here
https://mycodingwork.com/flutter-convert-string-to-datetime/
String startdate1="10/31/2022";
String endate1="11/02/2022";
DateTime start = new DateFormat("MM/dd/yyyy").parse(startdate1);
DateTime end = new DateFormat("MM/dd/yyyy").parse(enddate1);
DateTime s = DateTime(start.year, start.month, start.day);
DateTime to = DateTime(end.year, end.month, end.day);
int day= (to.difference(s).inHours / 24).round()+1;

datetime utc handling with DateTimeZoneHandling

i am trying to figure out why my dates on the client are different than my dates on the server... down below i have a breezeconfig class that i thought would allow my server side "unspecified" dates to be serialized as "utc"... however a date of "2011-08-11" is still being serialized as "2011-08-11T00:00:00.000" which i believe is missing the "Z" at the end in order to signify utc... any ideas? thank you
public class BreezeConfig : Breeze.WebApi.BreezeConfig
{
protected override Newtonsoft.Json.JsonSerializerSettings CreateJsonSerializerSettings()
{
var ret = base.CreateJsonSerializerSettings();
ret.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc;
return ret;
}
}
Setting ret.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc; doesn't work as expected because ret created by the base Breeze.WebApi.BreezeConfig.CreateJsonSerializerSettings() adds IsoDateTimeConverter to the ret.Converters list. By default IsoDateTimeConverter will not add 'Z' to the output string if DateTime.Kind is DateTimeKind.Unspecified. Like Jay Trabant answered -
breeze.js fixes this client-side.
With this knowledge it's ease to make your server return all dates as UTC:
var isoDateTimeConverter = ret.Converters.OfType<Newtonsoft.Json.Converters.IsoDateTimeConverter>().Single();
isoDateTimeConverter.DateTimeStyles = System.Globalization.DateTimeStyles.AssumeUniversal;
Because there is a bug in IsoDateTimeConverter - Issue with DateTimeStyles, it's better to completely remove IsoDateTimeConverter from the Converters collection and set DateTimeZoneHandling to Utc:
public class CustomBreezeConfig : Breeze.ContextProvider.BreezeConfig
{
protected override Newtonsoft.Json.JsonSerializerSettings CreateJsonSerializerSettings()
{
var settings = base.CreateJsonSerializerSettings();
settings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc;
var isoDateTimeConverter = settings.Converters.OfType<Newtonsoft.Json.Converters.IsoDateTimeConverter>().Single();
settings.Converters.Remove(isoDateTimeConverter);
return settings;
}
}
My guess is that your server datatype is a DateTime ( not a DateTime2 or DateTimeOffset), and as such has no explicit timezone information.
Breeze does not manipulate the datetimes going to and from the server in any way EXCEPT to add a UTZ timezone specifier to any dates returned from the server that do not already have one. This is only done because different browsers interpret dates without a timezone specifier differently and we want consistency between browsers.
This is discussed in more detail in the answer posted here. breezejs: date is not set to the right time

How to order by time and time only in C#?

I have this recorded in SQL Server:
1- startTime (datetime): 5/2/2009 08:30 (brazilian time format: d/m/y)
2- startTime (datetime): 4/2/2009 14:30 (brazilian time format: d/m/y)
My application just records time... the date it's SQL that generates by itself be getting the date of today.
When I ask VS 2008 to order this datetime fields, it returns me that code #2 is before #1, because 4/2/2009 comes before 5/2/2009.
But, actually I want it to order by time only and ignore the date.
Is it possible??
Thanks!!
André
from d in dates
orderby d.TimeOfDay
select d;
or
dates.OrderBy(d => d.TimeOfDay);
Note: This will work as long as this is plain LINQ and not LINQ-to-SQL. If you're using LINQ-to-SQL to query your database, you'll need something that will translate to SQL.
You might also try fixing your app so it always saves the same base date with the time (like '01/01/1900' or whatever) and then you do not have to do all these slow and inefficient date stripping operations every time you need to do a query.
Or as Joel said, truncate or strip off the date portion before you do the insert or update.
Well, you can't really store a datetime without a date, but you could just store the total seconds as an double (using #florian's method).
You'd have to add a second method to convert this back to a date in your object, if you still need a date, such as:
public class BusinessObjectWithDate
{
private string _someOtherDbField = "";
private double _timeInMS = 0; // save this to the database
// sort by this? in sql or in code. You don't really need this
// property, since TimeWithDate actually saves the _timeInMS field
public double TimeInMS {
get { return _timeInMS; }
}
public DateTime TimeWithDate { // sort by this too, if you want
get { return (new DateTime(1900,1,1).AddMilliseconds(_timeInMS)); }
set { _timeInMS = value.TimeOfDay.TotalMilliseconds; }
}
}
var f = new BusinessObjectWithDate();
MessageBox.Show( f.TimeWithDate.ToString() ); // 1/1/1900 12:00:00 AM
f.TimeWithDate = DateTime.Now;
MessageBox.Show( f.TimeWithDate.ToString() ); // 1/1/1900 1:14:57 PM
You could also just store the real date time, but always overwrite with 1/1/1900 when the value gets set. This would also work in sql
public class BusinessObjectWithDate
{
private DateTime _msStoredInDate;
public DateTime TimeWithDate
{
get { return _msStoredInDate; }
set {
var ms = value.TimeOfDay.TotalMilliseconds;
_msStoredInDate = (new DateTime(1900, 1, 1).AddMilliseconds(ms));
}
}
}
Try this in your sql:
ORDER BY startTime - CAST(FLOOR(CAST(startTime AS Float)) AS DateTime)

Resources