How to Round up the Date-Time nearest to 30 min interval in DART (Flutter)? - date

I would like to round DateTime to the nearest 30 mins. Is there rounding mechanism provided in DART?

I had a similar problem today and but it was to clamp to the next 15 mins.
DateTime nearestQuarter(DateTime val) {
return DateTime(val.year, val.month, val.day, val.hour,
15, 30, 45, 60][(val.minute / 15).floor()]);
}
or in your case
DateTime nearestHalf(DateTime val) {
return DateTime(val.year, val.month, val.day, val.hour,
[30, 60][(val.minute / 30).floor()]);
}
I just noticed you said 'nearest half hour'
DateTime nearestHalf(DateTime val) {
return DateTime(val.year, val.month, val.day, val.hour,
[0, 30, 60][(val.minute / 30).round()]);
}
https://francescocirillo.com/pages/anti-if-campaign

You can use this function to roundup the time.
DateTime alignDateTime(DateTime dt, Duration alignment,
[bool roundUp = false]) {
assert(alignment >= Duration.zero);
if (alignment == Duration.zero) return dt;
final correction = Duration(
days: 0,
hours: alignment.inDays > 0
? dt.hour
: alignment.inHours > 0
? dt.hour % alignment.inHours
: 0,
minutes: alignment.inHours > 0
? dt.minute
: alignment.inMinutes > 0
? dt.minute % alignment.inMinutes
: 0,
seconds: alignment.inMinutes > 0
? dt.second
: alignment.inSeconds > 0
? dt.second % alignment.inSeconds
: 0,
milliseconds: alignment.inSeconds > 0
? dt.millisecond
: alignment.inMilliseconds > 0
? dt.millisecond % alignment.inMilliseconds
: 0,
microseconds: alignment.inMilliseconds > 0 ? dt.microsecond : 0);
if (correction == Duration.zero) return dt;
final corrected = dt.subtract(correction);
final result = roundUp ? corrected.add(alignment) : corrected;
return result;
}
and then use it the following way
void main() {
DateTime dt = DateTime.now();
var newDate = alignDateTime(dt,Duration(minutes:30));
print(dt); // prints 2022-01-07 15:35:56.288
print(newDate); // prints 2022-01-07 15:30:00.000
}

This function converts a DateTime to the nearest 30 minute mark in a clock. Be warned that this 30 minute mark is obtained with respect to the local time zone of the machine in which this code runs on.
DateTime roundWithin30Minutes(DateTime d) {
final int deltaMinute;
if (d.minute < 15) {
deltaMinute = -d.minute; // go back to zero
} else if (d.minute < 45) {
deltaMinute = 30 - d.minute; // go to 30 minutes
} else {
deltaMinute = 60 - d.minute;
}
return d.add(Duration(
milliseconds: -d.millisecond,
// reset milliseconds to zero
microseconds: -d.microsecond,
// reset microseconds to zero,
seconds: -d.second,
// reset seconds to zero
minutes: deltaMinute));
}
If you are presenting this DateTime in another non local time zone whose offset duration is not a multiple of 30 minutes (eg: Nepal time zone is GMT+5:45) this implementation will not work.

extension DateTimeExt on DateTime {
DateTime get roundMin =>
DateTime(this.year, this.month, this.day, this.hour, () {
if (this.minute <= 15) {
return 0;
} else if (this.minute > 15 && this.minute <= 45) {
return 30;
} else {
return 60;
}
}());
}
You can do It with a simple extension just call it like this
var a = DateTime(2021, 5, 4, 3, 46, 4, 7);
print(a.roundMin);

Related

how to get difference(remaining time ) between '22:00:00' & '00:22:00' in flutter [duplicate]

I'm working on a flutter app as a project and I'm stuck with how to get the difference between two times. The first one I'm getting is from firebase as a String, which I then format to a DateTime using this:DateTime.parse(snapshot.documents[i].data['from']) and it gives me 14:00 for example. Then, the second is DateTime.now().
I tried all methods difference, subtract, but nothing works!
Please help me to get the exact duration between those 2 times.
I need this for a Count Down Timer.
This is an overview of my code:
.......
class _ActualPositionState extends State<ActualPosition>
with TickerProviderStateMixin {
AnimationController controller;
bool hide = true;
var doc;
String get timerString {
Duration duration = controller.duration * controller.value;
return '${duration.inHours}:${duration.inMinutes % 60}:${(duration.inSeconds % 60).toString().padLeft(2, '0')}';
}
#override
void initState() {
super.initState();
var d = Firestore.instance
.collection('users')
.document(widget.uid);
d.get().then((d) {
if (d.data['parking']) {
setState(() {
hide = false;
});
Firestore.instance
.collection('historyParks')
.where('idUser', isEqualTo: widget.uid)
.getDocuments()
.then((QuerySnapshot snapshot) {
if (snapshot.documents.length == 1) {
for (var i = 0; i < snapshot.documents.length; i++) {
if (snapshot.documents[i].data['date'] ==
DateFormat('EEE d MMM').format(DateTime.now())) {
setState(() {
doc = snapshot.documents[i].data;
});
Duration t = DateTime.parse(snapshot.documents[i].data['until'])
.difference(DateTime.parse(
DateFormat("H:m:s").format(DateTime.now())));
print(t);
}
}
}
});
}
});
controller = AnimationController(
duration: Duration(hours: 1, seconds: 10),
vsync: this,
);
controller.reverse(from: controller.value == 0.0 ? 1.0 : controller.value);
}
double screenHeight;
#override
Widget build(BuildContext context) {
screenHeight = MediaQuery.of(context).size.height;
return Scaffold(
.............
you can find the difference between to times by using:
DateTime.now().difference(your_start_time_here);
something like this:
var startTime = DateTime(2020, 02, 20, 10, 30); // TODO: change this to your DateTime from firebase
var currentTime = DateTime.now();
var diff = currentTime.difference(startTime).inDays; // HINT: you can use .inDays, inHours, .inMinutes or .inSeconds according to your need.
example from DartPad:
void main() {
final startTime = DateTime(2020, 02, 20, 10, 30);
final currentTime = DateTime.now();
final diff_dy = currentTime.difference(startTime).inDays;
final diff_hr = currentTime.difference(startTime).inHours;
final diff_mn = currentTime.difference(startTime).inMinutes;
final diff_sc = currentTime.difference(startTime).inSeconds;
print(diff_dy);
print(diff_hr);
print(diff_mn);
print(diff_sc);
}
Output: 3,
77,
4639,
278381,
Hope this helped!!
You can use the DateTime class to find out the difference between two dates.
DateTime dateTimeCreatedAt = DateTime.parse('2019-9-11');
DateTime dateTimeNow = DateTime.now();
final differenceInDays = dateTimeNow.difference(dateTimeCreatedAt).inDays;
print('$differenceInDays');
final differenceInMonths = dateTimeNow.difference(dateTimeCreatedAt).inMonths;
print('$differenceInMonths');
Use this code:
var time1 = "14:00";
var time2 = "09:00";
Future<int> getDifference(String time1, String time2) async
{
DateFormat dateFormat = DateFormat("yyyy-MM-dd");
var _date = dateFormat.format(DateTime.now());
DateTime a = DateTime.parse('$_date $time1:00');
DateTime b = DateTime.parse('$_date $time2:00');
print('a $a');
print('b $a');
print("${b.difference(a).inHours}");
print("${b.difference(a).inMinutes}");
print("${b.difference(a).inSeconds}");
return b.difference(a).inHours;
}
To compute a difference between two times, you need two DateTime objects. If you have times without dates, you will need to pick a date. Note that this is important because the difference between two times can depend on the date if you're using a local timezone that observes Daylight Saving Time.
If your goal is to show how long it will be from now to the next specified time in the local timezone:
import 'package:intl/intl.dart';
/// Returns the [Duration] from the current time to the next occurrence of the
/// specified time.
///
/// Always returns a non-negative [Duration].
Duration timeToNext(int hour, int minute, int second) {
var now = DateTime.now();
var nextTime = DateTime(now.year, now.month, now.day, hour, minute, second);
// If the time precedes the current time, treat it as a time for tomorrow.
if (nextTime.isBefore(now)) {
// Note that this is not the same as `nextTime.add(Duration(days: 1))` across
// DST changes.
nextTime = DateTime(now.year, now.month, now.day + 1, hour, minute, second);
}
return nextTime.difference(now);
}
void main() {
var timeString = '14:00';
// Format for a 24-hour time. See the [DateFormat] documentation for other
// format specifiers.
var timeFormat = DateFormat('HH:mm');
// Parsing the time as a UTC time is important in case the specified time
// isn't valid for the local timezone on [DateFormat]'s default date.
var time = timeFormat.parse(timeString, true);
print(timeToNext(time.hour, time.minute, time.second));
}
You can use this approch
getTime(time) {
if (!DateTime.now().difference(time).isNegative) {
if (DateTime.now().difference(time).inMinutes < 1) {
return "a few seconds ago";
} else if (DateTime.now().difference(time).inMinutes < 60) {
return "${DateTime.now().difference(time).inMinutes} minutes ago";
} else if (DateTime.now().difference(time).inMinutes < 1440) {
return "${DateTime.now().difference(time).inHours} hours ago";
} else if (DateTime.now().difference(time).inMinutes > 1440) {
return "${DateTime.now().difference(time).inDays} days ago";
}
}
}
And You can call it getTime(time) Where time is DateTime Object.

Flutter - check if the current time is in between a given hourly range

I want to check if the current time is between my opening time and my closing time, knowing that the close time can some times be 2 am and the opening time is 3 am, for example, I have been trying to handle this problem logically for 2 weeks now and I can't wrap my head around it, this is my best try yet:
open = new DateTime(now.year, now.month, now.day, open.hour, open.minute);
close = new DateTime(now.year, now.month, now.day, close.hour, close.minute);
midnight = new DateTime(now.year, now.month, now.day, midnight.hour, midnight.minute);
if(close.hour > midnight.hour && close.hour < open.hour){
if(now.hour < midnight.hour){
DateTime theClose = new DateTime(now.year, now.month, now.day + 1, close.hour, close.minute);
if(now.isBefore(theClose) && now.isAfter(open)){
sendIt(context, notes);
}else{
_showToast("this branch is closed right now");
}
}else{
open = new DateTime(now.year, now.month, now.day - 1, open.hour, open.minute);
if(now.isBefore(close) && now.isAfter(open)){
sendIt(context, notes);
}else{
_showToast("this branch is closed right now");
}
}
}else{
if(now.isBefore(close) && now.isAfter(open)){
sendIt(context, notes);
}else{
_showToast("this branch is closed right now");
}
}
//checks if restaurant is open or closed
// returns true if current time is in between given timestamps
//openTime HH:MMAM or HH:MMPM same for closedTime
bool checkRestaurentStatus(String openTime, String closedTime) {
//NOTE: Time should be as given format only
//10:00PM
//10:00AM
// 01:60PM ->13:60
//Hrs:Min
//if AM then its ok but if PM then? 12+time (12+10=22)
TimeOfDay timeNow = TimeOfDay.now();
String openHr = openTime.substring(0, 2);
String openMin = openTime.substring(3, 5);
String openAmPm = openTime.substring(5);
TimeOfDay timeOpen;
if (openAmPm == "AM") {
//am case
if (openHr == "12") {
//if 12AM then time is 00
timeOpen = TimeOfDay(hour: 00, minute: int.parse(openMin));
} else {
timeOpen =
TimeOfDay(hour: int.parse(openHr), minute: int.parse(openMin));
}
} else {
//pm case
if (openHr == "12") {
//if 12PM means as it is
timeOpen =
TimeOfDay(hour: int.parse(openHr), minute: int.parse(openMin));
} else {
//add +12 to conv time to 24hr format
timeOpen =
TimeOfDay(hour: int.parse(openHr) + 12, minute: int.parse(openMin));
}
}
String closeHr = closedTime.substring(0, 2);
String closeMin = closedTime.substring(3, 5);
String closeAmPm = closedTime.substring(5);
TimeOfDay timeClose;
if (closeAmPm == "AM") {
//am case
if (closeHr == "12") {
timeClose = TimeOfDay(hour: 0, minute: int.parse(closeMin));
} else {
timeClose =
TimeOfDay(hour: int.parse(closeHr), minute: int.parse(closeMin));
}
} else {
//pm case
if (closeHr == "12") {
timeClose =
TimeOfDay(hour: int.parse(closeHr), minute: int.parse(closeMin));
} else {
timeClose = TimeOfDay(
hour: int.parse(closeHr) + 12, minute: int.parse(closeMin));
}
}
int nowInMinutes = timeNow.hour * 60 + timeNow.minute;
int openTimeInMinutes = timeOpen.hour * 60 + timeOpen.minute;
int closeTimeInMinutes = timeClose.hour * 60 + timeClose.minute;
//handling day change ie pm to am
if ((closeTimeInMinutes - openTimeInMinutes) < 0) {
closeTimeInMinutes = closeTimeInMinutes + 1440;
if (nowInMinutes >= 0 && nowInMinutes < openTimeInMinutes) {
nowInMinutes = nowInMinutes + 1440;
}
if (openTimeInMinutes < nowInMinutes &&
nowInMinutes < closeTimeInMinutes) {
return true;
}
} else if (openTimeInMinutes < nowInMinutes &&
nowInMinutes < closeTimeInMinutes) {
return true;
}
return false;
}
bool isValidTimeRange(TimeOfDay startTime, TimeOfDay endTime) {
TimeOfDay now = TimeOfDay.now();
return ((now.hour > startTime.hour) || (now.hour == startTime.hour && now.minute >= startTime.minute))
&& ((now.hour < endTime.hour) || (now.hour == endTime.hour && now.minute <= endTime.minute));
}
As you have noticed, using DateTime in our case is not the best solution because it relies on the month/year/day.
Instead, we can make use of the TimeOfDay class that does not rely on a specific day, but only on the time:
List<TimeOfDay> openingTimeRange = [TimeOfDay(hour: 2, minute: 30), TimeOfDay(hour: 15, minute: 45)]; // as an example
bool isOpen(List<TimeOfDay> openingTimeRange) {
TimeOfDay now = TimeOfDay.now();
return now.hour >= openingTimeRange[0].hour
&& now.minute >= openingTimeRange[0].minute
&& now.hour <= openingTimeRange[1].hour
&& now.minute <= openingTimeRange[1].minute;
}
I have a simple solution if your time format is in 24 hours. For that you don't require any external library.
bool _getStoreOpenStatus(String openTime, String closeTime) {
bool result = false;
DateTime now = DateTime.now();
int nowHour = now.hour;
int nowMin = now.minute;
print('Now: H$nowHour M$nowMin');
var openTimes = openTime.split(":");
int openHour = int.parse(openTimes[0]);
int openMin = int.parse(openTimes[1]);
print('OpenTimes: H$openHour M$openMin');
var closeTimes = closeTime.split(":");
int closeHour = int.parse(closeTimes[0]);
int closeMin = int.parse(closeTimes[1]);
print('CloseTimes: H$closeHour M$closeMin');
if(nowHour >= openHour && nowHour <= closeHour) {
if(nowMin > openMin && nowMin < closeMin) result = true;
}
return result;
}
If you use your time in the digital format [0..23] for hours, then you can convert the time to the amount of seconds that have past in that day. Do the same for the ranges you would like to check and see whether the current time past in seconds are between the two number ranges (in seconds):
TimeOfDay now = TimeOfDay.now(); // or DateTime object
TimeOfDay openingTime = TimeOfDay(hours: ??, minutes:??); // or leave as DateTime object
TimeOfDay closingTime = TimeOfDay(hours: ??, minutes:??); // or leave as DateTime object
int shopOpenTimeInSeconds = openingTime.hour * 60 + openingTime.minute;
int shopCloseTimeInSeconds = closingTime.hour * 60 + closingTime.minute;
int timeNowInSeconds = now.hour * 60 + now.minute;
if (shopOpenTimeInSeconds <= timeNowInSeconds &&
timeNowInSeconds <= shopCloseTimeInSeconds) {
// OPEN;
} else {
// CLOSED;
}

How to compare timestamp to current time in flutter

This is my timestamp = "2020-05-29T17:43:39.622832+05:30". How can I pass it to a function readTimeStamp (it will give me error of not type of int)?
date = DateTime.parse(bookDetails.timestamp);
print(readTimestamp(date));
String readTimestamp(int timestamp) {
var now = DateTime.now();
var date = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
var diff = now.difference(date);
String time = '';
if (diff.inSeconds <= 0 ||
diff.inSeconds > 0 && diff.inMinutes == 0 ||
diff.inMinutes > 0 && diff.inHours == 0 ||
diff.inHours > 0 && diff.inDays == 0) {
} else if (diff.inDays > 0 && diff.inDays < 7) {
if (diff.inDays == 1) {
time = diff.inDays.toString() + ' DAY AGO';
} else {
time = diff.inDays.toString() + ' DAYS AGO';
}
} else {
if (diff.inDays == 7) {
time = (diff.inDays / 7).floor().toString() + ' WEEK AGO';
} else {
time = (diff.inDays / 7).floor().toString() + ' WEEKS AGO';
}
}
return time;
}
This is my function to return value like 3 day ago and all.
DateTime.parse returns a DateTime. readTimestamp appears to expect the number of seconds since the epoch, so you just need to use DateTime.millisecondsSinceEpoch and convert milliseconds to seconds:
print(readTimestamp(date.millisecondsSinceEpoch ~/ 1000));
Personally, if you control the readTimestamp function, I would rename its ambiguous timestamp argument to secondsSinceEpoch to make it clear what it expects. Even better would be to change its argument to take a DateTime directly instead of doing unnecessary DateTime <=> milliseconds <=> seconds conversions.
bool isAfterToday(Timestamp timestamp) {
return DateTime.now().toUtc().isAfter(
DateTime.fromMillisecondsSinceEpoch(
timestamp.millisecondsSinceEpoch,
isUtc: false,
).toUtc(),
);
}

How to format an integer to ss:m

I'm trying to get the following format from an int: ss:m (s = seconds, m = milliseconds) from a countdown timer. If there are minutes, the format should be mm:ss:m.
Here's my code:
final int currentTime = 100; // 10 seconds
final Duration duration = Duration(milliseconds: 100);
Timer.periodic(duration, (Timer _timer) {
if (currentTime <= 0) {
_timer.cancel();
} else {
currentTime--;
print(currentTime);
}
});
I tried adding currentTime to a Duration as milliseconds but it didn't give me the desired results. What am I doing wrong and how can I get it to the correct format?
I have used the below method the get it in hh:mm:ss / mm:ss format, you can tweak to get in s:mm
String getTime(int milis) {
Duration position = Duration(milliseconds: milis);
String twoDigits(int n) {
if (n >= 10) return "$n";
return "0$n";
}
String twoDigitMinutes = twoDigits(position.inMinutes.remainder(60));
String twoDigitSeconds = twoDigits(position.inSeconds.remainder(60));
String time;
if (twoDigits(position.inHours) == "00") {
time = "$twoDigitMinutes:$twoDigitSeconds";
} else {
time = "${twoDigits(position.inHours)}:$twoDigitMinutes:$twoDigitSeconds";
}
return time;
}
try Duration.toString() it'll give you a string formatted in your requirement
more precisely
Duration(milliseconds:currentTime).toString()
and 100 millis is not 10 seconds
10000 millis is 10 seconds

Dart: How to find number of days between two dates excluding Weekend or Predicate

I need to calculate number of days between two dates in Dart.
There is built in function for that.
leaveEndDate.difference(leaveStartDate).inDays
But I do not want weekends to be included.
Is there any way I can traverse between these 2 Dates or I can just exclude weekends.
I think you have no other choice than looping through all the days to check if this is a weekend day or not :
void main() {
DateTime date1 = DateTime(2019, 12, 01);
DateTime date2 = DateTime(2019, 12, 31);
print(getDifferenceWithoutWeekends(date1, date2));
}
int getDifferenceWithoutWeekends(DateTime startDate, DateTime endDate) {
int nbDays = 0;
DateTime currentDay = startDate;
while (currentDay.isBefore(endDate)) {
currentDay = currentDay.add(Duration(days: 1));
if (currentDay.weekday != DateTime.saturday && currentDay.weekday != DateTime.sunday) {
nbDays += 1;
}
}
return nbDays;
}
Result :
22
EDIT :
Another solution, not sure it is faster but can be useful if you need to identify the dates (you could return list<DateTime> instead of List<int> to see which day is a weekend day).
Here I build each days between the 2 dates and return 1 if this is not a weekend day, then sum the list :
void main() {
DateTime startDate = DateTime(2019, 12, 01);
DateTime endDate = DateTime(2019, 12, 31);
int nbDays = endDate.difference(startDate).inDays + 1;
List<int> days = List.generate(nbDays, (index) {
int weekDay = DateTime(startDate.year, startDate.month, startDate.day + (index)).weekday;
if (weekDay != DateTime.saturday && weekDay != DateTime.sunday) {
return 1;
}
return 0;
});
print(days.reduce((a, b) => a + b));
}
I have also prepared a function which will traverse to all dates between two dates in Dart and will calculate number of days inBetween.
int calculateDaysBetween(DateTime mStartDate, DateTime mEndDate) {
int leaveDays = mEndDate.difference(mStartDate).inDays + 1;
int leaveBalance = 0;
var mTempDateTime =
DateTime(mStartDate.year, mStartDate.month, mStartDate.day);
for (int i = 0; i < leaveDays; i++) {
mTempDateTime = DateTime(
mTempDateTime.year, mTempDateTime.month, mTempDateTime.day + 1);
if (mTempDateTime.weekday == DateTime.friday ||
mTempDateTime.weekday == DateTime.saturday) {
print('is weekend');
} else {
leaveBalance++;
}
print(mTempDateTime);
}
// Total number of days between two dates excluding weekends.
return leaveBalance;
}
Improve #Developine Answer and make it more reusable , I make 2 function.
1.Calculate Total Days Of Month
2.Calculate TotalWeekDayOfMonth
Get Total Days Of Month
int totalDaysOfMonth(int month, int year) {
final result = (month < 12) ? DateTime(year, month + 1, 0) : DateTime(year + 1, 1, 0);
return result.day;
}
Get Total WeekDay Of Month
int totalWeekDayOfMonth(int year, int month, {int day = 1}) {
int totalDayOfMonth = totalDaysOfMonth(year, month);
int result = 0;
DateTime tempDateTime = DateTime(year, month, day);
for (int i = day; i <= totalDayOfMonth; i++) {
tempDateTime = DateTime(tempDateTime.year, tempDateTime.month, i);
if (tempDateTime.weekday == DateTime.saturday || tempDateTime.weekday == DateTime.sunday) {
print('is weekend');
} else {
result++;
}
}
return result;
}
How To Use It
void main(){
final resultWithoutDay = totalWeekDayOfMonth(2019,12);
final resultWithDay = totalWeekDayOfMonth(2019,12,day: 16);
print("Without Day $resultWithoutDay"); // 22
print("With Day $resultWithDay"); // 12
}