Helpers

DateTime Helpers

This file contains all the common Date and Time helpers which can be used in the app.

Extension On TimeOfDay

Get TimeOfDay in HH:MM AM/PM format. DateTime extension contains toHMaa getter on the extension so it translates DateTime to HH:MM AM/PM.

final TimeOfDay time = TimeOfDay.now();
print(time.toHMaa);
String formatExt({String format = 'hh:mm a'}) =>
    DateFormat(format).format(DateTime(0, 0, 0, hour, minute));

Extension On DateTime

We have offset with respect to UTC time so we can change timezone with respect to UTC only. We will walk you through few use cases and how they should be handled.

Example of valid Timezones: Asia/Kolkata, ASIA/KOLKATA, asia/kolkata, Also check list of available timezones here

Usecase: We receive UTC time from database and we want to change it for specific timezone.

DateTime? date = DateTimeHelper.toTimezone('Asia/Kolkata', dateString);

Usecase: We have DateTime for specific timezone and we want to change it to UTC.

let's assume we have two properties in our model, one datekey and other timezonekey. And for some reason when we use date we don't want to use it as UTC.

DateTime? date = DateTimeHelper.fromTimezone(timezonekey, datekey);

Usecase: We have to change DateTime from one timezone (known priorly) to another timezone.

Let's say I have my DateTime according to ABC timezone and I want to change it to LMN timezone then First I'll have to convert ABC to UTC and then we can convert that UTC to LMN. But why do we have to go back to UTC when we want to change from one timezone to another timezone? Because we have time offsets respected to UTC.

let's assume we have two properties in our model, one datekey and other timezonekey. And newtimezone holds new timezone value.

DateTime? date = DateTimeHelper.fromTimezone(timezonekey, datekey)?.toTimezone(newtimezone);

Usecase: We have to change DateTime from one timezone (not known priorly) to another timezone.

for reference in below explaination:

RegionDateTime
EST2023-01-01 00:00:00 am
IST2023-01-01 10:30:00 am

Now why can't we convert DateTime from one timezone (not known priorly) to another timezone. e.g. let's try to convert EST (unknown) DateTime to IST DateTime. Date property from database looks something like: 2023-01-01 00:00:00 now we parse it in flutter, flutter gives us DateTime object as local. If I live in India it will give me DateTime object with same properties of 2023-01-01 00:00:00 and not with properties of 2023-01-01 10:30:00. Which is not correct. You can try everything/ available extension methods but you won't get correct results to show if you don't know the timezone.

DateTimeHelper

fromTimezone method: This method from DateTimeHelper class returns UTC datetime. timezone and datetime parameters are mendatory to pass, you can pass daylight true if the datetime is calculated depending on daylight, you can pass custom pattern if you're saving datetime in custom format.
static DateTime? fromTimezone(
  String timezone,
  String datetime, {
  String pattern = 'yyyy-MM-dd hh:mm:ss',
  bool daylight = false,
}) {
  // Will return UTC DateTime
  return DateFormat(pattern).parse(datetime, true).fromTimezone(timezone, daylight: daylight);
}

// Call
DateTime? datetime = DateTimeHelper.fromTimezone(
  'utc',
  '2023-01-01',
  pattern: 'yyyy-MM-dd',
);
toTimezone method: this method will give desired timezone datetime from UTC. You can pass daylight true if you want the results depending on daylight, you can pass custom pattern if you're saving datetime in custom format.
static DateTime? toTimezone(
  String timezone,
  String datetime, {
  String pattern = 'yyyy-MM-dd hh:mm:ss',
  bool daylight = false,
}) {
  return DateFormat(pattern).parse(datetime, true).toTimezone(timezone, daylight: daylight);
}

DateTime? datetime = DateTimeHelper.toTimezone(
  'Asia/Kolkata',
  '2023-01-01 10:30:00.000Z',
  pattern: 'yyyy-MM-dd hh:mm:ss.000Z',
);

Other DateTime Extensions

Get DateTime with zero milliseconds and microsecond
final DateTime date = DateTime.now();
print(date.resetMillisecond);
Get DateTime for n days before provided DateTime
final DateTime date = DateTime.now();
print(date.daysBefore(2));
Get DateTime for n days after provided DateTime
final DateTime date = DateTime.now();
print(date.daysAfter(2));
Get DateTime for the next day start
final DateTime date = DateTime.now();
print(date.nextDayStart);

returns xxxx-xx-xx 00:00:00.000

Get Date only (time is set to zero) (if DateTime type is UTC then return UTC otherwise return local)
final DateTime date = DateTime.now();
print(date.onlyDate);

returns year, month, date

Get Month only (time is set to zero and date is set to first) (if DateTime type is UTC then return UTC otherwise return local)
final DateTime date = DateTime.now();
print(date.onlyMonth);

returns xxxx-xx-01 00:00:00.000

Get Time only
final DateTime date = DateTime.now();
print(date.onlytime(01, 15));

can pass optional arguments hours and minutes, the first argument will be hour always. returns (epoch date + time) 1970-01-01 xx:xx:00.000z

Get UTC Time First Day Since Epoch
final DateTime date = DateTime.now();
print(date.utcTimeFirstDaySinceEpoch);

returns (epoch date + time with milli and micro secs) 1970-01-01 xx:xx:xx.xxxz

Get UTC DateTime
final DateTime date = DateTime.now();
print(date.asUtc);
Get Local DateTime
final DateTime date = DateTime.now();
print(date.asLocal);
Get Client DateTime
final DateTime date = DateTime.now();
print(date.asClient);
Get MMM DD HH:MM AM/PM formatted string
final DateTime date = DateTime.now();
print(date.toDateTimeString);
Get EEEE Month DD HH:MM AM/PM formatted string
final DateTime date = DateTime.now();
print(date.toFullDateTimeString);
Get EEE Month DD formated string
final DateTime date = DateTime.now();
print(date.toFullDateString);
Get HH:MM AM/PM formatted string
final DateTime date = DateTime.now();
print(date.toHMaa);
Get HH:MM:SS AM/PM formatted string
final DateTime date = DateTime.now();
print(date.toHHMMSS);
Get Month(short) Date formated string
final DateTime date = DateTime.now();
print(date.toMMMMdd);
Get Year-Month(short)-Date formated string
final DateTime date = DateTime.now();
print(date.toYyyymmmdd);
Get Date of Birth (YYYY-MM-DD) formatted string
final DateTime date = DateTime.now();
print(date.toDateOfBirth);
Get Custom formatted string

by default format will be : 'yyyy MMM dd, h:mm a'

mm will be used for Minutes and MM, MMM, MMMM will be used for Month.

DateTime date = DateTime.now();
Log.info(date.format(format: 'yyyy-MM-dd'), disableCloudLogging: true);

Extension On String

From String to DateTime
final DateTime date = '2023-01-01 00:00:00'.toDateTime();

you can pass a valid pattern in toDateTime function to convert the string from that format, default pattern is 'yyyy-mm-dd hh:mm:ss'

Add zeros as a prefix to equalize the length
const String number = '100';
print(number.zeroPrefix(6));
Parse string to int and double
const String number = '100';
final int? numInt = number.parseInt;
final double? numDouble = number.parseDouble;

Extension on Duration

Get formatted String
const Duration dur = Duration(days:3, hours: 20, minutes: 10);
print(dur.format);

will give output HH:MM:SS

Get HH:MM:SS formatted String
const Duration dur = Duration(days:3, hours: 20, minutes: 10);
print(dur.toHms);

will give output HH:MM:SS (Two Digit Hours, Two Digit Minutes, Two Digit Seconds)

Get MM:SS formatted String
const Duration dur = Duration(days:3, hours: 20, minutes: 10);
print(dur.toMs);

will give output MM:SS (Two Digit Minutes, Two Digit Seconds)

Extension on int

Get Local and UTC time from Milliseconds Since Epoch
final int millisecondsSinceEpoch = DateTime.now().millisecondsSinceEpoch;
print(millisecondsSinceEpoch.localDateTime);
print(millisecondsSinceEpoch.utcDateTime);
Get DateTime from Milliseconds Since Epoch
final int millisecondsSinceEpoch = DateTime.now().millisecondsSinceEpoch;
final DateTime date = millisecondsSinceEpoch.asDateTime(from: TimeZone.local);

The argument is optional.

Get DateTime from Milliseconds Since Epoch
final int millisecondsSinceEpoch = DateTime.now().millisecondsSinceEpoch;
final DateTime date = millisecondsSinceEpoch.asDateTime(from: TimeZone.local);

The from argument is optional.

Source code for datetime.dart

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

enum TimeZone { utc, local }

extension TimeOfDayExtension on TimeOfDay {
  // HH:MM AM
  String get toHMaa => DateFormat('hh:mm aaaa').format(DateTime(0, 0, 0, hour, minute));
}

// Extension for DateTime
extension DateTimeExtension on DateTime {
  String toTime(BuildContext context) => TimeOfDay.fromDateTime(asLocal).format(context);

  // Return DateTime with zero millisecond and microsecond
  DateTime get resetMillisecond => DateTime(year, month, day, hour, minute, second);

  DateTime daysBefore(int days) => subtract(Duration(days: days));

  DateTime daysAfter(int days) => add(Duration(days: days));

  DateTime get nextDayStart => onlyDate.daysAfter(1);

  DateTime get localTimeToday {
    DateTime now = DateTime.now();
    return DateTime(
      now.year,
      now.month,
      now.day,
      hour,
      minute,
      second,
      millisecond,
      microsecond,
    );
  }

  DateTime get onlyDate => isUtc ? DateTime.utc(year, month, day) : DateTime(year, month, day);

  DateTime get onlyMonth => isUtc ? DateTime.utc(year, month) : DateTime(year, month);

  DateTime onlyTime([int? hourArg, int? minuteArg]) =>
      DateTime.utc(1970, 1, 1, hourArg ?? hour, minuteArg ?? minute, 0, 0, 0);

  DateTime get utcTimeFirstDaySinceEpoch =>
      DateTime.utc(1970, 1, 1, hour, minute, second, millisecond, microsecond);

  // Convert local time as current utc
  // DateTime.now() = 2021-01-25 18:49:03.049422
  // DateTime.asUtc() = 2021-01-25 18:49:03.049422
  // DateTime.toUtc() = 2021-01-25 11:49:03.056208Z
  DateTime get asUtc =>
      isUtc ? this : DateTime.utc(year, month, day, hour, minute, second, millisecond, microsecond);

  DateTime get asLocal =>
      !isUtc ? this : DateTime(year, month, day, hour, minute, second, millisecond, microsecond);

  // Convert DateTime to String
  // Month(short) DD HH:MM AM/PM
  String get toDateTimeString => DateFormat('MMM dd h:mm a').format(this);

  // Day, Month DD HH:MM am/pm
  String get toFullDateTimeString => DateFormat('EEEE, MMMM dd h:mm a').format(this);

  // Day, Month DD am/pm
  String get toFullDateString => DateFormat('EEE, yyyy MMMM dd').format(this);

  // HH:MM am/pm
  String get toHMaa => DateFormat('hh:mm aaaa').format(this);

  // HH:MM:SS am/pm
  String get toHHMMSS => DateFormat('hh:mm:ss a').format(this);

  // Month DD
  String get toMMMMdd => DateFormat('MMMM dd').format(this);

  // Month(short) DD
  String get toMMMdd => DateFormat('MMM dd').format(this);

  // YYYY-MM-DD
  String get toYyyymmmdd => DateFormat('yyyy-MMM-dd').format(this);

  // YYYY-MM-DD
  String get toDateOfBirth => DateFormat('yyyy-MM-dd').format(this);

  // To query format: YYYY-MM-DD
  String get toQueryFormat => DateFormat('yyyy-MM-dd').format(this);
}

// Extension for DateTime from String
extension DateTimeStringExtendsion on String {
  // Convert to DateTime by pattern
  // https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
  DateTime toDateTime({String pattern = 'yyyy-MM-dd HH:mm:ss'}) {
    return DateFormat(pattern).parse(this, true).toLocal();
  }

  String get safe => this;

  String zeroPrefix(int count) {
    if (length >= count) {
      return this;
    } else {
      String builder = '';
      for (int i = 0; i < count - length; i++) {
        builder += '0';
      }
      builder += this;
      return builder;
    }
  }

  int? get parseInt => int.tryParse(this);

  double? get parseDouble => double.tryParse(this);
}

// Extension for duration
extension DurationExtension on Duration {
  Duration get safe => this;

  String get format => toString().split('.').first.padLeft(8, '0');

  // Add zero padding
  String _twoDigits(int n) {
    if (n >= 10) {
      return '$n';
    }
    return '0${max(n, 0)}';
  }

  // hours:minutes:seconds
  String get toHms {
    final String twoDigitHours = _twoDigits(inHours.remainder(24));
    final String twoDigitMinutes = _twoDigits(inMinutes.remainder(60));
    final String twoDigitSeconds = _twoDigits(inSeconds.remainder(60));
    return '$twoDigitHours:$twoDigitMinutes:$twoDigitSeconds';
  }

  // minutes:seconds
  String get toMs {
    final String twoDigitMinutes = _twoDigits(inMinutes.remainder(60));
    final String twoDigitSeconds = _twoDigits(inSeconds.remainder(60));
    return '$twoDigitMinutes:$twoDigitSeconds';
  }
}

// Extension for int
extension DateExtensions on int {
  DateTime get localDateTime => DateTime.fromMillisecondsSinceEpoch(this, isUtc: false);

  DateTime get utcDateTime => DateTime.fromMillisecondsSinceEpoch(this, isUtc: true);

  DateTime asDateTime({TimeZone from = TimeZone.utc}) {
    switch (from) {
      case TimeZone.local:
        return localDateTime;
      case TimeZone.utc:
      default:
        return utcDateTime;
    }
  }

  DateTime asLocal({TimeZone from = TimeZone.utc}) => asDateTime(from: from).asLocal;

  String toTime(BuildContext context, {TimeZone from = TimeZone.utc}) =>
      asDateTime(from: from).toTime(context);

  int localTimeToday({TimeZone from = TimeZone.utc}) =>
      asDateTime(from: from).localTimeToday.millisecondsSinceEpoch;

  int onlyDate({TimeZone from = TimeZone.utc}) =>
      asDateTime(from: from).onlyDate.millisecondsSinceEpoch;

  int onlyTime({TimeZone from = TimeZone.utc}) =>
      asDateTime(from: from).utcTimeFirstDaySinceEpoch.millisecondsSinceEpoch;

  int utcTimeFirstDaySinceEpoch({TimeZone from = TimeZone.utc}) =>
      asDateTime(from: from).utcTimeFirstDaySinceEpoch.millisecondsSinceEpoch;

  Duration asDuration() => Duration(milliseconds: this);
}

Copyright © 2024