How to get the closest timestamp to now from List?
I got a List of timestamps and I want to determine the closest timestamp in the future to current timestamp.
How can I achieve that?
Something like this? I am not sure how you are representing your timestamps so I have made the example by using DateTime objects:
void main() {
final dateTimes = <DateTime>[
DateTime(2020, 8, 1),
DateTime(2020, 8, 5),
DateTime(2020, 7, 13),
DateTime(2020, 7, 18),
DateTime(2020, 8, 15),
DateTime(2020, 8, 20)
];
final now = DateTime(2020, 7, 14);
final closetsDateTimeToNow = dateTimes.reduce(
(a, b) => a.difference(now).abs() < b.difference(now).abs() ? a : b);
print(closetsDateTimeToNow); // 2020-07-13 00:00:00.000
}
Note, the solution finds the closets timestamp in the list and looks both in the past and future.
Related
I am designing flutter app application that find the position of pupils through their total scores, I have used sort method but is not giving me a valid result.
'''List totals = [90, 50, 10, 5, 30, 9, 45];''' my result if I use I sort method 10, 30, 45, 50, 5, 90, 9.
this is what I want to be my result / 5, 9, 10, 30, 45, 50, 90
please help me out
I think that your List is of type String, that's why the order is different than comparing int. To fix this you parse the String to an int by using the parse method.
List<String> totals = ["90", "50", "10", "5", "30", "9", "45"];
totals.sort((a, b) => int.parse(a).compareTo(int.parse(b)));
print(totals); // [5, 9, 10, 30, 45, 50, 90]
try totals.sort((a, b) => a.compareTo(b));
I have the time in datetime format like below. I would like to extract the time from '20-Apr-2020 11:20:10' till '20-Apr-2020 12:40:50'. Do I need it to convert it first to datenumber or I can do it directly here?
Time_datenum={'20-Apr-2020 11:06:00','20-Apr-2020 11:20:10','20-Apr-2020 11:45:30','20-Apr-
2020 12:07:00','20-Apr-2020 12:35:40','20-Apr-2020 12:40:50','20-Apr-2020 13:07:00'};
Time_datetime = datetime(Time_One,'InputFormat','dd-MM-yyyy HH:mm:ss');
Time_datenum={'20-Apr-2020 11:06:00','20-Apr-2020 11:20:10','20-Apr-2020 11:45:30',...
'20-Apr-2020 12:07:00','20-Apr-2020 12:35:40','20-Apr-2020 12:40:50','20-Apr-2020 13:07:00'};
% Create a datetime array from a cell array of character vectors.
Time_datetime = datetime(Time_datenum, 'InputFormat', 'dd-MM-yyyy HH:mm:ss', 'Locale', 'en_GB');
% t = datetime(Year, Month, Day, Hour, Minute, Second)
Time_start = datetime(2020, 4, 20, 11, 20, 10);
Time_end = datetime(2020, 4, 20, 12, 40, 50);
% Extract the time.
Time_extracted = Time_datetime(Time_start <= Time_datetime & Time_datetime <= Time_end);
I have a string that consists of few numbers. First number is the number of the row, remaining are numbers in this row.(Array but string, kind of). The problem is that remaining numbers are unsorted, and I want to find the clearest way of sorting them without creating new List and sorting everything there.
String unsorted = '9, 12, 14, 11, 2, 10';
print(unsorted.sort()); // '9, 2, 10, 11, 12, 14'
You cant really avoid converting to a list of numbers if you want to sort it.
void main() {
print(sortNumString('9, 12, 14, 11, 2, 10')); // 2, 9, 10, 11, 12, 14
}
String sortNumString(String numString, [String separator = ', ']) =>
(numString.split(separator).map(int.parse).toList()..sort())
.join(separator);
The .. means to return the previous thing, the list, since sort returns void.
I'm not exactly experienced when it comes to dart programming language but this is what i came up with.
void main() {
var unsorted = "9, 12, 14, 11, 2, 10";
var nums_int = unsorted.split(", ").map(int.parse).toList();
nums_int.sort();
for (var n in nums_int) {
stdout.write(n.toString() + ", ");
}
}
That should give the expected output: "2, 9, 10, 11, 12, 14"
Hope this helps.
I am trying to get the difference in Days between two dates picked from a DatePicker. This works fine except for ONE single date : March 31.
The difference in Days between two DateTimes is wrong by 1 day when one of the dates is March 31. I know this is due to Light Saving and March is 30.9… days long and not 31, hence I am guessing, the error. But does anyone know how to fix this other than manually checking if a date is equal to March 31 and adding one day to the result ?
Two very simple examples that can be run in the Dart Pad :
DateTime aprilFirst = DateTime(2019, 3, 30);
DateTime marchThirtyFirst = DateTime(2019, 3, 31);
print(aprilFirst.difference(marchThirtyFirst).inDays); => -1
DateTime marchThirty = DateTime(2019, 4, 1);
DateTime marchThirtyFirst = DateTime(2019, 3, 31);
print(marchThirty.difference(marchThirtyFirst).inDays); => 0
UPDATE:
DateTime aprilFirst = DateTime(2019, 4, 1);
print(aprilFirst.add(Duration(days: -1))); => 2019-03-30 23:00:00.000
This should print 2019-03-31 23:00:00.000 !
I tried Günter Zöchbauer's solution of making the DateTimes UTC but the results are the exact same:
DateTime aprilFirst = DateTime(2019, 4, 1).toUtc();
DateTime marchThirty = DateTime(2019, 3, 30).toUtc();
DateTime marchThirtyFirst = DateTime(2019, 3, 31).toUtc();
print(aprilFirst.difference(marchThirtyFirst).inHours); => 23
print(aprilFirst.difference(marchThirtyFirst).inDays); => 0
print(marchThirty.difference(marchThirtyFirst).inHours); => -24
print(aprilFirst.add(Duration(days: -1))); => 019-03-30 22:00:00.000Z
#Günter Zöchbauer put me on the right path. DateTime(...).toUTC() will fail for difference calculations. However, using the DateTime.utc(...) constructor does the trick !
DateTime aprilFirst = DateTime.utc(2019, 4, 1);
DateTime marchThirty = DateTime.utc(2019, 3, 30);
DateTime marchThirtyFirst = DateTime.utc(2019, 3, 31);
print(aprilFirst.difference(marchThirtyFirst).inHours); => 24
print(aprilFirst.difference(marchThirtyFirst).inDays); => 1
print(marchThirty.difference(marchThirtyFirst).inHours); => -24
print(aprilFirst.add(Duration(days: -1))); => 2019-03-31 00:00:00.000Z
Don't do Date comparison or operations with local dates. Convert it to UTC first. Otherwise daylight savings and other local DateTime related exceptions will cause all kinds of surprising effects.
DateTime aprilFirst = DateTime(2019, 3, 30).toUtc();
DateTime marchThirtyFirst = DateTime(2019, 3, 31).toUtc();
print(aprilFirst.difference(marchThirtyFirst).inDays); => -1
If the result is a DateTime you can convert it back using xxx.toLocal()
There is also a constructor that allows to create an UTC DateTime instead of creating a local DateTime and then converting to UTC.
Try this package, Jiffy uses the momentJs concept of date-time difference
You can see dicussion here https://github.com/moment/moment/pull/571
DateTime aprilFirst = DateTime(2019, 3, 30);
DateTime marchThirtyFirst = DateTime(2019, 3, 31);
Jiffy(aprilFirst).diff(marchThirtyFirst, Units.DAY); // -1
// or
Jiffy([2019, 3, 30]).diff([2019, 3, 31], Units.DAY); // -1
DateTime marchThirty = DateTime(2019, 4, 1);
DateTime marchThirtyFirst = DateTime(2019, 3, 31);
Jiffy(marchThirty).diff(marchThirtyFirst, Units.DAY); // 1
Jiffy(marchThirty).diff(marchThirtyFirst, Units.HOUR); // 24
Jiffy(marchThirty).diff(marchThirtyFirst, Units.MONTH); // 0
2021 Based on answer
extension DateCalcs on DateTime {
DateTime get dateOnlyUTC => DateTime.utc(this.year,this.month,this.day);
}
You've already figured out that you get an unexpected result due to your locale observing Daylight Saving Time. Duration internally stores a number of microseconds; Duration.days is measured in terms of 24-hour increments and not in terms of calendar days. From the DateTime documentation:
The difference between two dates in different time zones is just the number of nanoseconds between the two points in time. It doesn't take calendar days into account. That means that the difference between two midnights in local time may be less than 24 hours times the number of days between them, if there is a daylight saving change in between. If the difference above is calculated using Australian local time, the difference is 7415 days and 23 hours, which is only 7415 whole days as reported by inDays.
See https://stackoverflow.com/a/71198806/ for a more general version of Benjamin's answer that computes the difference in days between two dates, ignoring the time (and therefore also ignoring Daylight Saving adjustments and time zones).
Is it possible to format the labels on the xAxis of a charts_flutter time series chart to display hh:mm:ss. This answer explains how to go about formatting the code to display months and days but the information I need to display is collected a few times a minute.
charts.AutoDateTimeTickFormatterSpec doesn't allow for specifying seconds. The OP on the above question alluded to a DateTimeFactory which is mentioned in the charts_flutter gallery, but I'm also unsure how to use this, or if it is even of any use in this situation.
new charts.TimeSeriesChart(
getSeries(item),
animate: false,
primaryMeasureAxis: new charts.NumericAxisSpec(
tickProviderSpec: new charts.BasicNumericTickProviderSpec(zeroBound: false)
),
domainAxis: new charts.DateTimeAxisSpec(
tickFormatterSpec: new charts.AutoDateTimeTickFormatterSpec(
hour: new charts.TimeFormatterSpec(format: 'hh', transitionFormat: 'dd/MM hh:mm'),
)
),
),
Alternatively, is there a different chart I could use that would allow for this functionality? I see that charts.BarChart allows for Strings on the xAxis, but I specifically need a line chart - is there some way of specifying strings rather than datetimes on a line chart if the above formatting is not possible?
Because of a setting down in MinuteTimeStepper, there's no point. The smallest interval that you can achieve between labels appears to be 5 minutes. The MinuteTimeStepper defaults to intervals of 5, 10, 15, 20 and 30 minutes.
class MinuteTimeStepper extends BaseTimeStepper {
static const _defaultIncrements = const [5, 10, 15, 20, 30];
It has a constructor that allows you to pass in your own list, but I can't figure out how to get that to work.
Instead, I just modified it to become const [1, 5, 10... and that now draws labels with a 1 minute gap (if space is available).
Given that the closest the labels will be drawn (even with this change) is every minute, there's no point in including seconds.
Taking the sample and modifying the series data to
new TimeSeriesSales(new DateTime(2018, 8, 22, 13, 00, 00), 15),
new TimeSeriesSales(new DateTime(2018, 8, 22, 13, 00, 30), 5),
new TimeSeriesSales(new DateTime(2018, 8, 22, 13, 01, 00), 25),
new TimeSeriesSales(new DateTime(2018, 8, 22, 13, 01, 30), 20),
new TimeSeriesSales(new DateTime(2018, 8, 22, 13, 02, 00), 10),
gives labels that read 1 00, 01 and 02 (1PM exactly, 1 minute past and 2 minutes past) which are generated by the default format of mm and h mm. Note that the points at the half minute are drawn, but not labeled, as expected.
If you wanted these in 24 hour format you could add a TimeFormatterSpec like
minute: new charts.TimeFormatterSpec(
format: 'mm', // or even HH:mm here too
transitionFormat: 'HH:mm',
),