How can I convert only an hour (Not date) in a string from UTC to localtime in flutter?
Solution 1
If you know the received time is in UTC and the date are "today" in UTC time, we can do something like this:
void main() {
print(parseHoursInUtc('3:52:59 PM')); // 2021-01-21 15:52:59.000Z
}
RegExp _timePattern =
RegExp(r'(?<hour>\d+):(?<minute>\d+):(?<second>\d+) (?<amPm>AM|PM)');
// timeString must be of the format "3:52:59 PM"
DateTime parseHoursInUtc(String timeString) {
final match = _timePattern.firstMatch(timeString);
final hour = int.parse(match.namedGroup('hour'));
final minute = int.parse(match.namedGroup('minute'));
final second = int.parse(match.namedGroup('second'));
final isPm = match.namedGroup('amPm') == 'PM';
final now = DateTime.now().toUtc();
return DateTime.utc(
now.year, now.month, now.day, isPm ? hour + 12 : hour, minute, second);
}
The methods returns a DateTime
in UTC mode which you can convert to local time with toLocal()
.
You can then use the intl
package to create a DateTimeFormat
which prints the time as you want it like this:
import 'package:intl/intl.dart';
void main() {
print(DateFormat.jms().format(parseHoursInUtc('3:52:59 PM').toLocal())); // 4:52:59 PM
}
RegExp _timePattern =
RegExp(r'(?<hour>\d+):(?<minute>\d+):(?<second>\d+) (?<amPm>AM|PM)');
// timeString must be of the format "3:52:59 PM"
DateTime parseHoursInUtc(String timeString) {
final match = _timePattern.firstMatch(timeString);
final hour = int.parse(match.namedGroup('hour'));
final minute = int.parse(match.namedGroup('minute'));
final second = int.parse(match.namedGroup('second'));
final isPm = match.namedGroup('amPm') == 'PM';
final now = DateTime.now().toUtc();
return DateTime.utc(
now.year, now.month, now.day, isPm ? hour + 12 : hour, minute, second);
}
I am in Denmark which are CET (UTC+1) right now (and with now I mean outside DST).
Solution 2
To get the time of any date in flutter you can use:
DateFormat("hh:mm aaa").format(DateTime.now()))
result: 5:40 p.m
Comments
-
nck over 1 year
I am making use of an API which states the following:
NOTE: All times are in UTC and summer time adjustments are not included in the returned data.
So I retrieved the data as follows:
String time = "3:52:59 PM";
I want to get that time as the phone localtime, so according to a similar question for dates it would be as follows:
final convertedTime = DateTime.parse(time).toLocal(); print(convertedTime.toString());
But this produces an error:
Invalid date format
I guess this issue comes because date time expects a date and not just hours, but I am not able to find anything else for just hours in
import 'package:intl/intl.dart';
How can I make this conversion, for example for GMT+1 taking into account the summertime, or any other timezone of the phone?
In my example the expected time would be:
String time = "4:52:59 PM";
-
julemand101 about 3 yearsIf you don't have any date, what should the time be if the UTC->localtime transformation ends up on a different day? How would you handle the DST? (What I am trying to say... it seems really odd that this API does not give any date. And without any date, the concept of converting from UTC to localtime does not make any sense)
-
Matt Johnson-Pint about 3 yearsTo echo @julemand101 - You'll need a date to do this correctly. Even if you wanted to use "today" there's a chance for off-by-one errors near transitions because the current UTC date might differ from the current local date depending on time zone.
-
Matt Johnson-Pint about 3 yearsOn the string format, you can use
DateTimeFormat.parse
and passtrue
for UTC. Though you still need a date or it will default to1970-01-01
. -
nck about 3 years@julemand101 I just reviewed it and the query is 'today', but is the today of the UTC time, I don't know if I can just use the 'today' of the device.
-
nck about 3 years@MattJohnson-Pint it crashes with the
Invalid date format
exception
-
-
Antonin GAVREL almost 3 yearsThat's a great answer but had some trouble as it seems the regex only works with double quote:
final RegExp _timePattern = RegExp(r"(?<hour>\d+):(?<minute>\d+) (?<amPm>AM|PM)")
(I didn't keep the seconds). -
julemand101 almost 3 years@AntoninGAVREL Not sure what you are doing but it should not matter if you are using
""
or''
forString
in Dart unless yourString
itself contain"
or'
(which is not the case in my answer). My guess is therefore your have made a mistake when copying by answer. If not, could you tell what error you are getting? You can read about how to represent aString
in Dart here: dart.dev/guides/language/language-tour#strings -
julemand101 almost 3 years@AntoninGAVREL One detail about the solution is that it is made before null-safety was introduced in Dart so it does not have any handling of potential null-value of
match
, or the result fromnamedGroup
. -
Antonin GAVREL almost 3 yearsI know, just tell you that oddly it was not working with single quote.