nck
nck

Reputation: 2221

How can I convert only an hour (Not date) in a string from UTC to localtime in flutter?

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";

Upvotes: 1

Views: 1280

Answers (2)

Edinson Peña
Edinson Peña

Reputation: 11

To get the time of any date in flutter you can use:

DateFormat("hh:mm aaa").format(DateTime.now()))

result: 5:40 p.m

Upvotes: 1

julemand101
julemand101

Reputation: 31259

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).

Upvotes: 3

Related Questions