f050d10a1d
Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
104 lines
2.6 KiB
Dart
104 lines
2.6 KiB
Dart
import 'package:flutter_timezone/flutter_timezone.dart';
|
|
import 'package:timezone/data/latest.dart' as tzdata;
|
|
import 'package:timezone/timezone.dart' as tz;
|
|
|
|
class TimeService {
|
|
static const String estLocationName = 'America/New_York';
|
|
|
|
static bool _initialized = false;
|
|
|
|
static Future<void> initialize() async {
|
|
if (_initialized) {
|
|
return;
|
|
}
|
|
|
|
tzdata.initializeTimeZones();
|
|
final localName = await FlutterTimezone.getLocalTimezone();
|
|
tz.setLocalLocation(tz.getLocation(localName));
|
|
_initialized = true;
|
|
}
|
|
|
|
static tz.Location get est => tz.getLocation(estLocationName);
|
|
|
|
static tz.TZDateTime estNow() => tz.TZDateTime.now(est);
|
|
|
|
static DateTime localNow() => tz.TZDateTime.now(tz.local);
|
|
|
|
static tz.TZDateTime estDeadlinePassedAt(int year, int month) {
|
|
return tz.TZDateTime(est, year, month, 2, 0, 0);
|
|
}
|
|
|
|
static tz.TZDateTime estFirstReminderAt(int year, int month) {
|
|
return tz.TZDateTime(est, year, month, 2, 0, 5);
|
|
}
|
|
|
|
static bool isOnTimeByDeadline(DateTime paidAtUtc, int year, int month) {
|
|
final estPaidAt = tz.TZDateTime.from(paidAtUtc, est);
|
|
final cutoff = tz.TZDateTime(est, year, month, 1, 23, 59, 59, 999);
|
|
return !estPaidAt.isAfter(cutoff);
|
|
}
|
|
|
|
static DateTime applyQuietHours({
|
|
required DateTime localTime,
|
|
required int quietHourStart,
|
|
required int fallbackHour,
|
|
}) {
|
|
if (localTime.hour >= quietHourStart) {
|
|
return DateTime(
|
|
localTime.year,
|
|
localTime.month,
|
|
localTime.day + 1,
|
|
fallbackHour,
|
|
);
|
|
}
|
|
|
|
return localTime;
|
|
}
|
|
|
|
static DateTime nextEligibleLocal({
|
|
required DateTime candidate,
|
|
required int quietHourStart,
|
|
required int fallbackHour,
|
|
}) {
|
|
final now = localNow();
|
|
var result = candidate;
|
|
|
|
if (result.isBefore(now)) {
|
|
result = now.add(const Duration(minutes: 1));
|
|
}
|
|
|
|
if (result.hour >= quietHourStart) {
|
|
result = DateTime(
|
|
result.year,
|
|
result.month,
|
|
result.day + 1,
|
|
fallbackHour,
|
|
);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
static bool monthAtOrAfter({
|
|
required int year,
|
|
required int month,
|
|
required int pivotYear,
|
|
required int pivotMonth,
|
|
}) {
|
|
return year > pivotYear || (year == pivotYear && month >= pivotMonth);
|
|
}
|
|
|
|
static bool monthBefore({
|
|
required int year,
|
|
required int month,
|
|
required int otherYear,
|
|
required int otherMonth,
|
|
}) {
|
|
return year < otherYear || (year == otherYear && month < otherMonth);
|
|
}
|
|
|
|
static String monthKey(int year, int month) {
|
|
return '$year-${month.toString().padLeft(2, '0')}';
|
|
}
|
|
}
|