DateTime in UTC not converting to Local - datetime

I'm receiving a DateTime response from API that's sets the timezone to UTC.
But when I try to convert the received data using toLocal() it doesn't convert.
my local time is HKT
here's my code.
//TIME DIFFERENCE
getNotificationDate(DateTime date) {
date = date.toUtc();
final convertedDate = date.toLocal();
final dateNow = DateTime.now();
print('TIMENOW: ' + dateNow.toString());
print('TIMENOTIFC: ' + convertedDate.toString());
final difference = dateNow.difference(convertedDate);
print('DIFFERENCE: ' + difference.toString());
return getDurationFormat(difference);
}
EDIT:
date is the DateTime I'm receiving from the API. which is in UTC timezone.
I used print('TIMEZONENAME: ' + date.timeZoneName; and it automatically sets the timezone to HKT. that's why it does nothing when I try to use date.toLocal()

Flutter gave us the easiest way to convert it.
You just need to pass utc: true while parsing your date.
var dateTime = DateFormat("yyyy-MM-dd HH:mm:ss").parse(dateUtc, true);
var dateLocal = dateTime.toLocal();
Input:
Assume my TimeZone : +05:30
UTC Date -> 2020-02-12 23:57:02.000
Output:
Local Date -> 2020-02-12 18:27:02.019660

// you have time in utc
var dateUtc = DateTime.now().toUtc();
print("dateUtc: $dateUtc"); // 2019-10-10 12:05:01
// convert it to local
var dateLocal = dateUtc.toLocal();
print("local: $dateLocal"); // 2019-10-10 14:05:01
Can you see the difference in hours, in utc it is 12 and locally it is 14.

Firstly, convert your Sting to DateTime.
> DateTime dateTime = DateTime.parse(json['pickUpTime']);
Secondly, add timeZoneOffSet to your converted date time it will convert utc to your local time.
> dateTime = dateTime.add(DateTime.parse(json['pickUpTime']).timeZoneOffset);
Final Code
DateTime dateTime = DateTime.parse(json['pickUpTime']);
dateTime = dateTime.add(DateTime.parse(json['pickUpTime']).timeZoneOffset);

You can try this code:
getNotificationDate(DateTime date) {
date = DateTime.utc(date.year,date.month,date.day,date.hour,date.minute,date.second);;
final convertedDate = date.toLocal();
final dateNow = DateTime.now();
print('TIMENOW: ' + dateNow.toString());
print('TIMENOTIFC: ' + convertedDate.toString());
final difference = dateNow.difference(convertedDate);
print('DIFFERENCE: ' + difference.toString());
return getDurationFormat(difference);
}

I've done something like this.
String dateTimeFormatter(String dateTime, {String? format}) {
return DateFormat(format ?? 'yyyy/MM/dd, hh:mm a')
.format(DateTime.parse(dateTime).toLocal())
.toString();
}
just pass the format which you want to display in your app.

If somebody needs to parse a UTC timestamp in isoformat, for example something like this:
>>> from datetime import datetime
>>> datetime.utcnow().format()
'2021-07-20T19:35:19.769891'
Then you can parse this and convert this to local time by
DateTime parseDatetimeFromUtc({required String isoFormattedString}){
var dateTime = DateTime.parse(isoFormattedString + '+00:00');
return dateTime.toLocal();
}
The '+00:00' is append here as the timezone information part which I do not send over my API to save some bytes. Maybe this helps someone who is in the same situation.
Of course you do not need this hardcoded suffix if you use a timezone aware timestamp in your backend:
>>> from datetime import datetime, timezone
>>> datetime.now(timezone.utc).isoformat()
'2021-07-20T19:42:36.538195+00:00'

For those who parsing TimeStamp from Firestore.
*sentAt is Timestamp
String timeToDate = widget.sentAt.toDate().toString();
var dateTime = DateFormat("yyyy-MM-dd HH:mm:ss").parse(timeToDate, true);
var dateLocal = dateTime.toLocal();

this is how i converted to my required time .which was showing as
I/flutter ( 5709): 16 Apr 08:30 PM 2021
when using the
var date=DateFormat("dd MMM hh:mm a y").format(DateTime.fromMillisecondsSinceEpoch(start*1000));
print(date);
but after using this code i got my right time
var date=DateFormat("dd MMM hh:mm a y").format(DateTime.fromMillisecondsSinceEpoch(start*1000).toUtc());
print(date);
which is
I/flutter ( 5709): 16 Apr 03:00 PM 2021

I tried several examples and forums, but it kept getting me the incorrect date time for my zone, The only way I made it work correctly was by using the GMT package
var nowLocal = DateTime.now();
print("toUtc: ${nowLocal.toUtc()}");
print("toLocalDateTime ${nowLocal.toLocalDateTime()}");
print("toLocal ${nowLocal.toLocal()}");
print("toIso8601String ${nowLocal.toIso8601String()}");
final timeZoneOffsetInHours = DateTime.now().timeZoneOffset.inHours;
final nowGMT = await GMT.now();
print("GMT: $nowGMT");
final nowActual = nowGMT?.add(Duration(hours: timeZoneOffsetInHours));
print("nowActual $nowActual");

Two solutions I implemented
var date = DateFormat("yyyy-MM-ddTHH:mm:ss").parse(json, true);
var dateLocal = date.toLocal();
Other solutions add "Z"
You need to indicate a timezone to DateTime.parse, otherwise it assumes local time. From the dartdoc:
var date = DateTime.parse("${dateString}Z").toLocal();
var dateFormat = date2.toLocal();

Install intl package from pub.dev
add following line :
import 'package:intl/intl.dart';
You can make an extension like below so it will be very helpful and easy to use anywhere in a whole project.
//just make sure you have passed the right date format of utc("yyyy-MM-dd HH:mm:ss"). I have passed by default my format.
//for example
// 2020-11-25 24:12:36 -> "yyyy-MM-dd HH:mm:ss"
DateTime localDate=utcDateTime.toLocalDateTime();
//for different formats you can pass your own dateFormat for utcDate like below:
// 20-11-25 24:12:36 -> "yy-MM-dd HH:mm:ss"
DateTime localDate=utcDateTime.toLocalDateTime("yy-MM-dd HH:mm:ss");
extension DateTimeExtension on DateTime {
DateTime toLocalDateTime({String format = "yyyy-MM-dd HH:mm:ss"}) {
var dateTime = DateFormat(format).parse(this.toString(), true);
return dateTime.toLocal();
}
}

convert utc number to DateTime:
DateTime utcToDateTime(int utc) {
return DateTime(1970, 1, 1).add(Duration(seconds: utc));
}
//test
DateTime d = utcToDateTime(1649297709);
print(d);

Related

SwiftUI - How to format Firestore Timestamp in a TextView

I have a startTime field returned from Firestore which is defined as a timestamp. I am using Codable to specify startTime as a date in Swift.
I cannot see how to convert the full date provided by timestamp to just a time.
Text("\(startTime)" gives me "Monday, September 7, 2020 at 12:00:00 PM British Summer Time"
Use the following example as reference to get the format you want
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
let newDateString = dateFormatter.string(from: yourDate)
Here you can find the different format options.
Here is a more complete (ready to use) answer:
import Foundation
import FirebaseFirestore
func formatTransactionTimpestamp(_ timestamp: Timestamp?) -> String {
if let timestamp = timestamp {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .short
let date = timestamp.dateValue()
dateFormatter.locale = Locale.current
let formatted = dateFormatter.string(from: date)
return formatted
}
return ""
}
Apple docs
Firebase docs

How do I convert a date/time string to a DateTime object in Dart?

Say I have a string
"1974-03-20 00:00:00.000"
It is created using DateTime.now(),
how do I convert the string back to a DateTime object?
DateTime has a parse method
var parsedDate = DateTime.parse('1974-03-20 00:00:00.000');
https://api.dartlang.org/stable/dart-core/DateTime/parse.html
There seem to be a lot of questions about parsing timestamp strings into DateTime. I will try to give a more general answer so that future questions can be directed here.
Your timestamp is in an ISO format. Examples: 1999-04-23, 1999-04-23 13:45:56Z, 19990423T134556.789. In this case, you can use DateTime.parse or DateTime.tryParse. (See the DateTime.parse documentation for the precise set of allowed inputs.)
Your timestamp is in a standard HTTP format. Examples: Fri, 23 Apr 1999 13:45:56 GMT, Friday, 23-Apr-99 13:45:56 GMT, Fri Apr 23 13:45:56 1999. In this case, you can use dart:io's HttpDate.parse function.
Your timestamp is in some local format. Examples: 23/4/1999, 4/23/99, April 23, 1999. You can use package:intl's DateFormat class and provide a pattern specifying how to parse the string:
import 'package:intl/intl.dart';
...
var dmyString = '23/4/1999';
var dateTime1 = DateFormat('d/M/y').parse(dmyString);
var mdyString = '04/23/99';
var dateTime2 = DateFormat('MM/dd/yy').parse(mdyString);
var mdyFullString = 'April 23, 1999';
var dateTime3 = DateFormat('MMMM d, y', 'en_US').parse(mdyFullString));
See the DateFormat documentation for more information about the pattern syntax.
DateFormat limitations:
DateFormat cannot parse dates that lack explicit field separators. For such cases, you can resort to using regular expressions (see below).
Prior to version 0.17.0 of package:intl, yy did not follow the -80/+20 rule that the documentation describes for inferring the century, so if you use a 2-digit year, you might need to adjust the century afterward.
As of writing, DateFormat does not support time zones. If you need to deal with time zones, you will need to handle them separately.
Last resort: If your timestamps are in a fixed, known, numeric format, you always can use regular expressions to parse them manually:
var dmyString = '23/4/1999';
var re = RegExp(
r'^'
r'(?<day>[0-9]{1,2})'
r'/'
r'(?<month>[0-9]{1,2})'
r'/'
r'(?<year>[0-9]{4,})'
r'$',
);
var match = re.firstMatch(dmyString);
if (match == null) {
throw FormatException('Unrecognized date format');
}
var dateTime4 = DateTime(
int.parse(match.namedGroup('year')!),
int.parse(match.namedGroup('month')!),
int.parse(match.namedGroup('day')!),
);
See https://stackoverflow.com/a/63402975/ for another example.
(I mention using regular expressions for completeness. There are many more points for failure with this approach, so I do not recommend it unless there's no other choice. DateFormat usually should be sufficient.)
import 'package:intl/intl.dart';
DateTime brazilianDate = new DateFormat("dd/MM/yyyy").parse("11/11/2011");
you can just use : DateTime.parse("your date string");
for any extra formating, you can use "Intl" package.
void main() {
var dateValid = "30/08/2020";
print(convertDateTimePtBR(dateValid));
}
DateTime convertDateTimePtBR(String validade)
{
DateTime parsedDate = DateTime.parse('0001-11-30 00:00:00.000');
List<String> validadeSplit = validade.split('/');
if(validadeSplit.length > 1)
{
String day = validadeSplit[0].toString();
String month = validadeSplit[1].toString();
String year = validadeSplit[2].toString();
parsedDate = DateTime.parse('$year-$month-$day 00:00:00.000');
}
return parsedDate;
}
a string can be parsed to DateTime object using Dart default function DateTime.parse("string");
final parsedDate = DateTime.parse("1974-03-20 00:00:00.000");
Example on Dart Pad
String dateFormatter(date) {
date = date.split('-');
DateFormat dateFormat = DateFormat("yMMMd");
String format = dateFormat.format(DateTime(int.parse(date[0]), int.parse(date[1]), int.parse(date[2])));
return format;
}
I solved this by creating, on the C# server side, this attribute:
using Newtonsoft.Json.Converters;
public class DartDateTimeConverter : IsoDateTimeConverter
{
public DartDateTimeConverter()
{
DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFK";
}
}
and I use it like this:
[JsonConverter(converterType: typeof(DartDateTimeConverter))]
public DateTimeOffset CreatedOn { get; set; }
Internally, the precision is stored, but the Dart app consuming it gets an ISO8601 format with the right precision.
HTH

node RRule check if rule day is today

I am using 'rrule.js' library in node to parse my RRule. I would like to know if current day is same as rule day. It works on most cases but not all. I also use moment.js to compare. The issue is in "rule.after()". It should include the current day but it doesn't.
function checkIfToday(rruleStr){
var RRule = require('rrule').RRule;
var moment = require('moment');
var rule = RRule.fromString(rruleStr);
// Convert all dates into UTC before comparison
var todayutc = moment().utc(); // today in UTC
var nextOccurrence = rule.after(todayutc,inc=true); // next rule date including today
var nextOccurutc = moment(nextOccurrence).utc(); // convert today into utc
var match = moment(nextOccurutc).isSame(todayutc, 'day'); // check if 'DAY' is same
return match;
}
Any idea what's the best way to do this.
Thanks.
This worked for me. Try setting the time of todayutc back to the beginning of the day using moment's startOf method:
function checkIfToday(rruleStr){
var RRule = require('rrule').RRule;
var moment = require('moment');
var rule = RRule.fromString(rruleStr);
// Convert all dates into UTC before comparison
var todayutc = moment().utc().startOf('day'); // today in UTC
var nextOccurrence = rule.after(todayutc, true); // next rule date including today
var nextOccurutc = moment(nextOccurrence).utc(); // convert today into utc
var match = moment(nextOccurutc).isSame(todayutc, 'day'); // check if 'DAY' is same
return match;
}

How to compare two dates with each other in Flex?

I have a standard ISO8601 date string:
2004-02-12T15:19:21+00:00
I want to know if this date is older than 10 minutes ago in Flex. So basically:
if ("2004-02-12T15:19:21+00:00" > current_time - 10mins) {
// do whatever
}
What would the syntax be in Flex? I'm basically stuck at trying to convert the string into a Flex Date Object without parsing it character by character.
If you don;t care about the timezone i.e. the date string is in the same timezone as where you are running the application then this should work.
var date:Date = DateFormatter.parseDateString("2004-02-12T15:19:21+00:00");
var now:Date = new Date();
var tenMinAgo:Number = now.time - 1000*60*10;
if (date.time < tenMinAgo) {
trace("More than 10 min ago");
}

How to parse an ISO formatted date in Flex (AS3)?

How can I parse an ISO date string into a date object in Flex (AS3)?
e.g.
2009-12-08T04:23:23Z
2009-12-08T04:23:23.342-04:00
etc...
import com.adobe.utils.DateUtil;
var dateString:String = "2009-03-27T16:28:22.540-04:00";
var d:Date = DateUtil.parseW3CDTF(dateString);
trace(d);
var s:String = DateUtil.toW3CDTF(d);
trace(s);
[trace] Fri Mar 27 16:28:22 GMT-0400 2009
[trace] 2009-03-27T20:28:22-00:00
Turns out DateUtil handles everything in the W3C Date and Time spec. AS3 Dates do not maintain milliseconds, but they'll just be dropped if available.
Note that the W3C output is converted to UTC (aka GMT, or Zulu time).
Example function to convert ISO into Date format
public function isoToDate(value:String):Date
{
var dateStr:String = value;
dateStr = dateStr.replace(/\-/g, "/");
dateStr = dateStr.replace("T", " ");
dateStr = dateStr.replace("Z", " GMT-0000");
return new Date(Date.parse(dateStr));
}
Here is an implementation: http://blog.flexexamples.com/2008/02/02/parsing-iso-dates-with-flex-and-actionscript/
(Sorry ff just isn't showing the linking button and I am too lazy to do it myself.)

Resources