Initial commit

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
2026-03-19 20:29:22 +01:00
commit f050d10a1d
137 changed files with 5877 additions and 0 deletions
+103
View File
@@ -0,0 +1,103 @@
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')}';
}
}