253 lines
5.5 KiB
Dart
253 lines
5.5 KiB
Dart
/// [Time] is used as a way to serialize and deserialize time based notations.
|
|
///
|
|
/// When interacting with this, you can even parse Durations
|
|
|
|
class Time {
|
|
int days;
|
|
int hours;
|
|
int minutes;
|
|
int seconds;
|
|
|
|
Time(
|
|
{required this.days,
|
|
required this.hours,
|
|
required this.minutes,
|
|
required this.seconds}) {
|
|
autofix();
|
|
}
|
|
|
|
static Time fromDuration(Duration duration) {
|
|
int days = duration.inDays;
|
|
int hours = duration.inHours.remainder(24);
|
|
int minutes = duration.inMinutes.remainder(60);
|
|
int seconds = duration.inSeconds.remainder(60);
|
|
|
|
return Time(days: days, hours: hours, minutes: minutes, seconds: seconds);
|
|
}
|
|
|
|
Duration toDuration() {
|
|
return Duration(
|
|
days: days, hours: hours, minutes: minutes, seconds: seconds);
|
|
}
|
|
|
|
int getTotalSeconds() {
|
|
int current = 0;
|
|
current += seconds;
|
|
|
|
current += (minutes * 60); // 60 seconds in a minute
|
|
|
|
current += (hours * 60 * 60); // 60 seconds, 60 minutes in an hour
|
|
|
|
return current;
|
|
}
|
|
|
|
void add(Time time) {
|
|
seconds += time.getTotalSeconds();
|
|
autofix();
|
|
}
|
|
|
|
void subtract(Time time) {
|
|
int sec = getTotalSeconds();
|
|
sec -= time.getTotalSeconds();
|
|
|
|
apply(sec);
|
|
}
|
|
|
|
void tickDown() {
|
|
int sec = getTotalSeconds();
|
|
sec--;
|
|
|
|
apply(sec);
|
|
}
|
|
|
|
void tickUp() {
|
|
int sec = getTotalSeconds();
|
|
sec++;
|
|
|
|
apply(sec);
|
|
}
|
|
|
|
void apply(int seconds) {
|
|
hours = 0;
|
|
minutes = 0;
|
|
this.seconds = seconds;
|
|
if (this.seconds < 0) this.seconds = 0;
|
|
|
|
autofix();
|
|
}
|
|
|
|
void autofix() {
|
|
int totalSeconds = getTotalSeconds();
|
|
if (totalSeconds < 0) totalSeconds = 0;
|
|
|
|
int one_day = (1 * 60 * 60 * 24);
|
|
int one_hour = (1 * 60 * 60);
|
|
int one_minute = (1 * 60);
|
|
|
|
int days = (totalSeconds / 60 / 60 / 24).round();
|
|
totalSeconds -= (days * one_day);
|
|
|
|
int hours = (totalSeconds / 60 / 60).round();
|
|
totalSeconds -= (hours * one_hour);
|
|
|
|
int minutes = (totalSeconds / 60).round();
|
|
totalSeconds -= (minutes * one_minute);
|
|
|
|
int seconds = totalSeconds;
|
|
|
|
this.days = days;
|
|
this.hours = hours;
|
|
this.minutes = minutes;
|
|
this.seconds = seconds;
|
|
}
|
|
|
|
Time copy() {
|
|
return Time(days: days, hours: hours, minutes: minutes, seconds: seconds);
|
|
}
|
|
|
|
factory Time.copy(Time other) {
|
|
return Time(
|
|
days: other.days,
|
|
hours: other.hours,
|
|
minutes: other.minutes,
|
|
seconds: other.seconds);
|
|
}
|
|
|
|
factory Time.fromNotation(String notation) {
|
|
int days = 0;
|
|
int hours = 0;
|
|
int minutes = 0;
|
|
int seconds = 0;
|
|
|
|
List<String> current = [];
|
|
String val = notation;
|
|
if (val.indexOf('d') == -1) {
|
|
days = 0;
|
|
} else {
|
|
current = val.split('d');
|
|
days = int.parse(current[0]);
|
|
|
|
if (current.length == 2) {
|
|
val = current[1];
|
|
} else
|
|
val = "";
|
|
}
|
|
if (val.indexOf('h') == -1) {
|
|
hours = 0;
|
|
} else {
|
|
current = val.split('h');
|
|
hours = int.parse(current[0]);
|
|
|
|
if (current.length == 2)
|
|
val = current[1];
|
|
else
|
|
val = "";
|
|
}
|
|
|
|
if (val.indexOf('m') == -1) {
|
|
minutes = 0;
|
|
} else {
|
|
current = val.split('m');
|
|
minutes = int.parse(current[0]);
|
|
|
|
if (current.length == 2)
|
|
val = current[1];
|
|
else
|
|
val = "";
|
|
}
|
|
|
|
if (val.indexOf('s') == -1) {
|
|
seconds = 0;
|
|
} else {
|
|
current = val.split('s');
|
|
seconds = int.parse(current[0]);
|
|
|
|
if (current.length == 2)
|
|
val = current[1];
|
|
else
|
|
val = "";
|
|
}
|
|
|
|
if (val != "") {
|
|
seconds += int.parse(val);
|
|
}
|
|
|
|
return Time(days: days, hours: hours, minutes: minutes, seconds: seconds);
|
|
}
|
|
|
|
@override
|
|
String toString() {
|
|
List<String> parts = [];
|
|
|
|
if (days > 0) parts.add('${days}d');
|
|
if (hours > 0) parts.add('${hours}h');
|
|
if (minutes > 0) parts.add('${minutes}m');
|
|
if (seconds > 0) parts.add('${seconds}s');
|
|
|
|
return parts.join(' ');
|
|
}
|
|
}
|
|
|
|
/// Provides some functionality dart lacks internally.
|
|
///
|
|
/// WARNING: A potential race condition can be met by using the nano time here.
|
|
///
|
|
/// Long run times may eventually reach a maximum possible value. To prevent this, code should make use of the resetNanoTime function.
|
|
class TimeUtils {
|
|
/// This locks the internal timer and stops execution
|
|
bool _tslock = false;
|
|
int _ns = 0;
|
|
|
|
TimeUtils._();
|
|
static TimeUtils? _inst;
|
|
|
|
factory TimeUtils() {
|
|
_inst ??= TimeUtils._();
|
|
return _inst!;
|
|
}
|
|
|
|
/// Returns a unix timestamp
|
|
static int getUnixTimestamp() {
|
|
return (DateTime.now().millisecondsSinceEpoch / 1000).round();
|
|
}
|
|
|
|
/// Converts a unix timestamp back into DateTime format.
|
|
static DateTime parseTimestamp(int unixTimestamp) {
|
|
return DateTime.fromMillisecondsSinceEpoch(unixTimestamp * 1000);
|
|
}
|
|
|
|
/// Starts the time tracker.
|
|
static void initTimeTracker() {
|
|
TimeUtils tu = TimeUtils();
|
|
tu._tslock = false;
|
|
tu._timeLoop();
|
|
}
|
|
|
|
/// Stops the time tracker
|
|
static void stopTimeTracker() {
|
|
TimeUtils tu = TimeUtils();
|
|
tu._tslock = true;
|
|
}
|
|
|
|
/// Resets the currently tracked nanoTime.
|
|
static void resetNanoTime() {
|
|
TimeUtils tu = TimeUtils();
|
|
tu._ns = 0;
|
|
}
|
|
|
|
/// This is the loop which will keep a facsimile of nanoseconds since start.
|
|
Future<void> _timeLoop() async {
|
|
_ns = 0;
|
|
while (!_tslock) {
|
|
await Future.delayed(
|
|
Duration(microseconds: 1)); // Simulate 1 microsecond delay
|
|
_ns += 1000; // Increment by 1000 nanoseconds (1 microsecond)
|
|
}
|
|
}
|
|
|
|
/// Returns the current simulated nanotime.
|
|
static int getNanoTime() {
|
|
TimeUtils tu = TimeUtils();
|
|
return tu._ns;
|
|
}
|
|
}
|