I have this process, the user selects 2 dates. The system will then check if there are weekends. Weekends are:
Friday
Saturday
Sunday
Every time there are weekends, there would be additional charge + $10 PER DAY OF THE WEEKEND.
I have this code below, what I want is the process to add the surcharge.
http://jsfiddle.net/xtD5V/71/
function isWeekend(date1, date2) {
var d1 = new Date(date1),
d2 = new Date(date2),
isWeekend = false;
while (d1 < d2) {
var day = d1.getDay();
isWeekend = (day == 6) || (day == 0);
if (isWeekend) { return true; }
d1.setDate(d1.getDate() + 1);
}
return false;
}
alert(isWeekend(date1, date2));
You can opt to try this option.
Loop through all the dates and check for weekends like you did.
Store it in a variable
Option 1:
function noOfWeekends(date1, date2) {
//record number of weekends
var no_of_weekends = 0;
var d1 = new Date(date1),
d2 = new Date(date2),
isWeekend = false;
while (d1 < d2) {
var day = d1.getDay();
isWeekend = (day == 6) || (day == 0);
if (isWeekend) { no_of_weekends++; }
d1.setDate(d1.getDate() + 1);
}
return no_of_weekends;
}
//noOfWeekends now returns the number of weekends. You can do more stuff with it
alert(noOfWeekends(date1, date2) > 0);
alert("surcharge: " + noOfWeekends * 10);
*P/s: You can opt to write a formula to calculate the number of weekends without a loop since we can derive the information from your current day and number of days left. Do give it a try.
Related
TimeOfDay documentation has no comparison operator and primitive comparison does not work. My only solution that I can thinking of right now is to convert TimeOfDay to DateTime and use DateTime's difference method.
Does anyone have a better solution?
Convert it to a double then compare.
double toDouble(TimeOfDay myTime) => myTime.hour + myTime.minute/60.0
extension TimeOfDayExtension on TimeOfDay {
int compareTo(TimeOfDay other) {
if (hour < other.hour) return -1;
if (hour > other.hour) return 1;
if (minute < other.minute) return -1;
if (minute > other.minute) return 1;
return 0;
}
}
Thanks from #Lucas idea, you can calculate hour and minute by
TimeOfDay yourTime ;
TimOfDay nowTime = TimeOfDay.now()
double _doubleYourTime = yourTime.hour.toDouble() +
(yourTime.minute.toDouble() / 60);
double _doubleNowTime = nowTime.hour.toDouble() +
(nowTime.minute.toDouble() / 60);
double _timeDiff = _doubleYourTime - _doubleNowTime;
double _hr = _timeDiff.truncate();
double _minute = (_timeDiff - _timeDiff.truncate()) * 60;
print('Here your Happy $_hr Hour and also $_minute min');
I calculated the difference by turning both values into minute-counts, and comparing those :)
TimeOfDay now = TimeOfDay.now();
int nowInMinutes = now.hour * 60 + now.minute;
TimeOfDay testDate = TimeOfDay(hour: 2, minute: 20);
int testDateInMinutes = testDate.hour * 60 + testDate.minute;
You can use this method. Where you have to provide starttime and endTime in TimesofDay format.
getTime(startTime, endTime) {
bool result = false;
int startTimeInt = (startTime.hour * 60 + startTime.minute) * 60;
int EndTimeInt = (endTime.hour * 60 + endTime.minute) * 60;
int dif = EndTimeInt - startTimeInt;
if (EndTimeInt > startTimeInt) {
result = true;
} else {
result = false;
}
return result;
}
LikeThis
getTime(v1, v2);
TimeOfDay n = TimeOfDay.now();
int nowSec = (n.hour * 60 + n.minute) * 60;
int veiSec = (t.hour * 60 + t.minute) * 60;
int dif = veiSec - nowSec;
Card(
child: ListTile(
onTap: () {
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
).then((TimeOfDay time) {
double _doubleyourTime =
time.hour.toDouble() + (time.minute.toDouble() /60);
double _doubleNowTime = TimeOfDay.now().hour.toDouble() +
(TimeOfDay.now().minute.toDouble() / 60);`enter code here`
if (_doubleyourTime > _doubleNowTime) {
print('correct format')
});
} else {
print('Sorry You can not set the time')
}
});
},
//dense: true,
leading: Icon(Icons.timer),
title: Text(
'Today On Time',`enter code here`
),
),
),
We can actually use the subtract operator.
Code to make magic happen :
Here I wanted to get the difference in time after the user selects the time (in TimeOfDay format) using showTimePicker()
// current time will be used to find the difference between the time selected by the user.
TimeOfDay _cur_time = TimeOfDay(hour: DateTime.now().hour, minute: DateTime.now().minute);
// scheduled time will be updated as soon as the user inputs a new time using the showTimePicker() function available in Flutter Material librabry.
TimeOfDay _scheduled_time = TimeOfDay(hour: DateTime.now().hour, minute: DateTime.now().minute);
// toDouble Function to convert time to double so that we can compare time and check that the time selected is greater than current time.
double toDouble(TimeOfDay myTime) => myTime.hour + myTime.minute / 60.0;
void _selectTime() async {
Flutter Material widget to select time.
final TimeOfDay? newTime = await showTimePicker(
context: context,
initialTime: _scheduled_time,
);
//Check if the selected time is greater than the cur time
if (toDouble(newTime!) > toDouble(_cur_time)) {
setState(() {
_scheduled_time = newTime;
});
}
}
Function to get the difference between cur time and selected time.
Duration _getDelayedDuration(){
var hourDelay = _scheduled_time.hour - _cur_time.hour;
print(hourDelay);
var minuteDelay = _scheduled_time.minute - _cur_time.minute;
print(minuteDelay);
return Duration(hours: hourDelay, minutes: minuteDelay);
}
Solution for negative duration calculations
All these answers are pretty good but they didn't help me when I had a user select a range of times in my app. In order to calculate the total duration of the specified time period, I tried all the solutions which work pretty well but fail in certain scenarios. The scenarios are:
When the start time comes after the end time (i.e- when the duration is supposed to be over 12 hours)
When the start time is before 12am at the night and end time is after that
And the code to overcome it is:
String durationFromTimeOfDay(TimeOfDay? start, TimeOfDay? end) {
if (start == null || end == null) return '';
// DateTime(year, month, day, hour, minute)
final startDT = DateTime(9, 9, 9, start.hour, start.minute);
final endDT = DateTime(9, 9, 10, end.hour, end.minute);
final range = DateTimeRange(start: startDT, end: endDT);
final hours = range.duration.inHours % 24;
final minutes = range.duration.inMinutes % 60;
final _onlyHours = minutes == 0;
final _onlyMinutes = hours == 0;
final hourText = _onlyMinutes
? ''
: '$hours${_onlyHours ? hours > 1 ? ' hours' : ' hour' : 'h'}';
final minutesText = _onlyHours
? ''
: '$minutes${_onlyMinutes ? minutes > 1 ? ' mins' : ' min' : 'm'}';
return hourText + minutesText;
}
It is important to note that you need to prefill the DateTime for end TimeOfDay with a day value which is greater than the same in start DateTime. The other parameters (for year and month) can be anything you want.
This outputs a really nicely formatted string that is short, concise, and extremely legible
This, however, doesn't satisfy the requirement that the solution is devoid of conversion to DateTime. But at least it uses a different approach over the difference method. And this makes the correct duration calculation more reliable in a few lines of code comparatively.
I don't think this is possible. You can use .subtract in DateTime as also .difference
I need to get day of year (day1 is 1rst of january), week of year, and month of year from a dart DateTime object.
I did not find any available library for this. Any idea ?
[ORIGINAL ANSWER - Please scroll below to the updated answer, which has an updated calculation]
Week of year:
/// Calculates week number from a date as per https://en.wikipedia.org/wiki/ISO_week_date#Calculation
int weekNumber(DateTime date) {
int dayOfYear = int.parse(DateFormat("D").format(date));
return ((dayOfYear - date.weekday + 10) / 7).floor();
}
The rest is available through DateFormat (part of the intl package).
[UPDATED ANSWER]
As pointed out by Henrik Kirk in a comment, the original answer did not include the necessary correction for certain dates. Here is a full implementation of the ISO week date calculation.
/// Calculates number of weeks for a given year as per https://en.wikipedia.org/wiki/ISO_week_date#Weeks_per_year
int numOfWeeks(int year) {
DateTime dec28 = DateTime(year, 12, 28);
int dayOfDec28 = int.parse(DateFormat("D").format(dec28));
return ((dayOfDec28 - dec28.weekday + 10) / 7).floor();
}
/// Calculates week number from a date as per https://en.wikipedia.org/wiki/ISO_week_date#Calculation
int weekNumber(DateTime date) {
int dayOfYear = int.parse(DateFormat("D").format(date));
int woy = ((dayOfYear - date.weekday + 10) / 7).floor();
if (woy < 1) {
woy = numOfWeeks(date.year - 1);
} else if (woy > numOfWeeks(date.year)) {
woy = 1;
}
return woy;
}
Day of year
final date = someDate;
final diff = now.difference(new DateTime(date.year, 1, 1, 0, 0));
final diffInDays = diff.inDays;
Week of year
final date = someDate;
final startOfYear = new DateTime(date.year, 1, 1, 0, 0);
final firstMonday = startOfYear.weekday;
final daysInFirstWeek = 8 - firstMonday;
final diff = date.difference(startOfYear);
var weeks = ((diff.inDays - daysInFirstWeek) / 7).ceil();
// It might differ how you want to treat the first week
if(daysInFirstWeek > 3) {
weeks += 1;
}
Month of year
final monthOfYear = new DateTime.now().month;
Caution: That's not battle-tested code.
Try this really simple dart package, Jiffy. The code below will help
To get date day of year
// This will return the day of year from now
Jiffy().dayOfYear; // 295
// You can also pass in a dateTime object
Jiffy(DateTime(2019, 1, 3)).dayOfYear; // 3
To get week of year
Jiffy().week; // 43
// You can also pass in an Array or Map
Jiffy([2019, 1, 3]).week; // 1
To get month of year
Jiffy().month; // 10
Jiffy({
"year": 2019,
"month": 1,
"day": 3
}).month; // 1
Hope this answer helps
This is my implementation of ISO 8601 Week of Year in Dart:
int getWeekOfYear(DateTime date) {
final weekYearStartDate = getWeekYearStartDateForDate(date);
final dayDiff = date.difference(weekYearStartDate).inDays;
return ((dayDiff + 1) / 7).ceil();
}
DateTime getWeekYearStartDateForDate(DateTime date) {
int weekYear = getWeekYear(date);
return getWeekYearStartDate(weekYear);
}
int getWeekYear(DateTime date) {
assert(date.isUtc);
final weekYearStartDate = getWeekYearStartDate(date.year);
// in previous week year?
if(weekYearStartDate.isAfter(date)) {
return date.year - 1;
}
// in next week year?
final nextWeekYearStartDate = getWeekYearStartDate(date.year + 1);
if(isBeforeOrEqual(nextWeekYearStartDate, date)) {
return date.year + 1;
}
return date.year;
}
DateTime getWeekYearStartDate(int year) {
final firstDayOfYear = DateTime.utc(year, 1, 1);
final dayOfWeek = firstDayOfYear.weekday;
if(dayOfWeek <= DateTime.thursday) {
return addDays(firstDayOfYear, 1 - dayOfWeek);
}
else {
return addDays(firstDayOfYear, 8 - dayOfWeek);
}
}
Note that the "week year" is not always the calendar year, it could also be the one before or after:
void printWeekOfYear(DateTime date) {
print('week ${getWeekOfYear(date)} in year ${getWeekYear(date)}');
}
printWeekOfYear(DateTime.utc(2017, 1, 1));
// --> week 52 in year 2016
printWeekOfYear(DateTime.utc(2019, 12, 31));
// --> week 1 in year 2020
Number Week according to ISO 8601
int isoWeekNumber(DateTime date) {
int daysToAdd = DateTime.thursday - date.weekday;
DateTime thursdayDate = daysToAdd > 0 ? date.add(Duration(days: daysToAdd)) : date.subtract(Duration(days: daysToAdd.abs()));
int dayOfYearThursday = dayOfYear(thursdayDate);
return 1 + ((dayOfYearThursday - 1) / 7).floor();
}
int dayOfYear(DateTime date) {
return date.difference(DateTime(date.year, 1, 1)).inDays;
}
Dart SDK2.8.4 and later:
day of the year , with no packages:
void main(){
final now = new DateTime.now();
final todayInDays = now.difference(new DateTime(now.year,1,1,0,0)).inDays; //return 157
}
reference (official)> inDays, from Dart Official documentation
I wrote another solution based on your answers, it seem to work fine, but please feel free to give me feedback if you see a problem:
class DateUtils {
static int currentWeek() {
return weekOfYear(DateTime.now());
}
static int weekOfYear(DateTime date) {
DateTime monday = weekStart(date);
DateTime first = weekYearStartDate(monday.year);
int week = 1 + (monday.difference(first).inDays / 7).floor();
if (week == 53 && DateTime(monday.year, 12, 31).weekday < 4)
week = 1;
return week;
}
static DateTime weekStart(DateTime date) {
// This is ugly, but to avoid problems with daylight saving
DateTime monday = DateTime.utc(date.year, date.month, date.day);
monday = monday.subtract(Duration(days: monday.weekday - 1));
return monday;
}
static DateTime weekEnd(DateTime date) {
// This is ugly, but to avoid problems with daylight saving
// Set the last microsecond to really be the end of the week
DateTime sunday = DateTime.utc(date.year, date.month, date.day, 23, 59, 59, 999, 999999);
sunday = sunday.add(Duration(days: 7 - sunday.weekday));
return sunday;
}
static DateTime weekYearStartDate(int year) {
final firstDayOfYear = DateTime.utc(year, 1, 1);
final dayOfWeek = firstDayOfYear.weekday;
return firstDayOfYear.add(Duration(days: (dayOfWeek <= DateTime.thursday ? 1 : 8) - dayOfWeek));
}
}
getWeekOfYear(){
DateTime _kita=DateTime.now();
int d=DateTime.parse("${_kita.year}-01-01").millisecondsSinceEpoch;
int t= _kita.millisecondsSinceEpoch;
double daydiff= (t- d)/(1000 * (3600 * 24));
double week= daydiff/7;
return(week.ceil());
}
Tested and working you do not need any package
This calculation works for me.
int dayOfWeek({DateTime date}) {
if (date == null)
date = DateTime.now();
int w = ((dayOfYear(date) - date.weekday + 10) / 7).floor();
if (w == 0) {
w = getYearsWeekCount(date.year-1);
} else if (w == 53) {
DateTime lastDay = DateTime(date.year, DateTime.december, 31);
if (lastDay.weekday < DateTime.thursday) {
w = 1;
}
}
return w;
}
int getYearsWeekCount(int year) {
DateTime lastDay = DateTime(year, DateTime.december, 31);
int count = dayOfWeek(date: lastDay);
if (count == 1)
count = dayOfWeek(date: lastDay.subtract(Duration(days: 7)));
return count;
}
int dayOfYear(DateTime date) {
int total = 0;
for (int i = 1; i < date.month; i++) {
total += getDayOfMonth(date.year, i);
}
total+=date.day;
return total;
}
int getDayOfMonth(int year, int month) {
final List<int> days = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
if (year % 4 == 0) days[DateTime.february]++;
return days[month];
}
the previous most voted solution is not working, if the year changes. for example has December 2020 a 53. week and if i change to January 2021 the previous solution computed 0 and not 53.
so i wrote a DateTime extension to cover year change.
int get weekNumber {
if (weekday > DateTime.thursday) {
int toSubstract = weekday - DateTime.thursday;
DateTime thursday = subtract(Duration(days: toSubstract));
if (thursday.year != year) {
return thursday.weekNumber;
}
}
int dayOfYear = int.parse(format('D'));
return ((dayOfYear - weekday + 10) / 7).floor();
}
The correct answer of #András Szepesházi but as DateTime extension
extension DateTimeExt on DateTime {
/// Calculates week number from a date as per https://en.wikipedia.org/wiki/ISO_week_date#Calculation
int get weekNumber {
int dayOfYear = int.parse(DateFormat("D").format(this));
int woy = ((dayOfYear - weekday + 10) / 7).floor();
if (woy < 1) {
woy = _numOfWeeks(year - 1);
} else if (woy > _numOfWeeks(year)) {
woy = 1;
}
return woy;
}
/// Calculates number of weeks for a given year as per https://en.wikipedia.org/wiki/ISO_week_date#Weeks_per_year
int _numOfWeeks(int year) {
DateTime dec28 = DateTime(year, 12, 28);
int dayOfDec28 = int.parse(DateFormat("D").format(dec28));
return ((dayOfDec28 - dec28.weekday + 10) / 7).floor();
}
}
static int getWeekNumber(DateTime datetime) {
var day1 = DateTime(datetime.year);
DateTime firstMonday;
switch (day1.weekday) {
case 1: // mon
firstMonday = day1;
break;
case 2: // tue
firstMonday = day1.add(const Duration(days: 6));
break;
case 3: // wed
firstMonday = day1.add(const Duration(days: 5));
break;
case 4: // thir
firstMonday = day1.add(const Duration(days: 4));
break;
case 5: // fri
firstMonday = day1.add(const Duration(days: 3));
break;
case 6: // sat
firstMonday = day1.add(const Duration(days: 2));
break;
case 7: // sun
firstMonday = day1.add(const Duration(days: 1));
break;
default:
firstMonday = day1;
}
Duration sinceStartOfYear = datetime.diff(firstMonday);
double weekNo = (sinceStartOfYear.inDays / 7);
var no = weekNo.floor();
return no + 1;
}
My full tested method.
Currently I'm trying to make a query that based on the day of week gets movies out of the database of that week.
So a movie week is from Thursday to next Wednesday.
When its Sunday, I only want movies from Sunday to Wednesday.
If its Tuesday, I only want movies from Tuesday to Wednesday etc.
I'm really getting stuck on what you can and cannot do in asp any suggestions?
Here's my code so far:
public IEnumerable<Viewing> GetUpcomingWeekViews()
{
var viewingList1 = _efdbContext.Viewing.ToList();
DateTime currentDate = DateTime.Now.Date;
var viewingList = _efdbContext.Viewing.ToList();
DateTime startOfWeek = DateTime.Now.
return viewingList.Where(v => (
v.StartTime.Date == currentDate.Date) &&
(v.StartTime.TimeOfDay > currentDate.TimeOfDay)
).OrderBy(v => v.StartTime);
}
Use the DayOfWeek property of DateTime:
var date = DateTime.Now;
var currentWeekday = (int)date.DayOfWeek;
const int wednesday = 3; // sunday is 0
var offset = 0;
// if today is before wednesday, go to next wednesday
if (currentWeekday < wednesday) {
offset = wednesday - currentWeekday;
}
// if today is wednesday, add a whole week till next wednesday
if(currentWeekday == wednesday) {
offset = 7;
}
// if today is after wednesday, go to wednesday in a week
if(currentWeekday > wednesday) {
offset = wednesday - currentWeekday + 7;
}
var nextWednesday = date.AddDays(offset);
Fiddle
First calculate the offset from Current date to desired date using DateOfWeek
public int CalculateOffset(DayOfWeek current, DayOfWeek desired) {
// f( c, d ) = [7 - (c - d)] mod 7
// f( c, d ) = [7 - c + d] mod 7
// c is current day of week and 0 <= c < 7
// d is desired day of the week and 0 <= d < 7
int c = (int)current;
int d = (int)desired;
int offset = (7 - c + d) % 7;
return offset == 0 ? 7 : offset;
}
And add that offset to the Date of the current DateTime
public IEnumerable<Viewing> GetUpcomingWeekViews(DayOfWeek desiredDayOfWeek = DayOfWeek.Thursday) {
DateTime minStartTime = DateTime.Now;
var currentDayOfWeek = minStartTime.DayOfWeek;
int offset = CalculateOffset(currentDayOfWeek, desiredDayOfWeek);
DateTime maxStartTime = minStartTime.Date.AddDays(offset);
var viewingList = dbContext.Viewing.ToList();
return viewingList
.Where(v => minStartTime <= v.StartTime && v.StartTime < maxStartTime)
.OrderBy(v => v.StartTime);
}
In my project I needed to add a timecode(offset) with another timecode(original), to show it in a custom html5 video player.
00:00:17.16 --->(original timecode) +
07:49:42.08 --->(offset timecode)
-----------
07:49:59:24 sincle framerate is 23, this time code is rounded to
07:49:60:01 (7 hrs : 49 mins :60 secs and 1 frame) which is equal to
07:50:00:01 ------>(Resultant timecode)
===========
It is easy and I wrote som code for that in javascript.
function AddTimeCodeWithOffset(Offset, Original, framerate) {
var newTime = Original;
var framerate = parseFloat(framerate);
if (Offset != '00:00:00:00') {
var arOff = Offset.split(':');
var arOrg = Original.split(':');
var hour = parseInt(arOff[0]) + parseInt(arOrg[0]);
var minute = parseInt(arOff[1]) + parseInt(arOrg[1]);
var second = parseInt(arOff[2]) + parseInt(arOrg[2]);
var frame = parseInt(arOff[3]) + parseInt(arOrg[3]);
if (frame >= framerate) {
frame = Math.round(frame - framerate);
second = second + 1;
}
if (second >= 60) {
second = second - 60;
minute = minute + 1;
}
if (minute >= 60) {
minute = minute - 60;
hour = hour + 1;
}
if (frame < 10) { frame = '0' + frame.toString(); }
if (second < 10) { second = '0' + second.toString(); }
if (minute < 10) { minute = '0' + minute.toString(); }
if (hour < 10) { hour = '0' + hour.toString(); }
newTime = hour + ':' + minute + ':' + second + ':' + frame;
}
return newTime;
}
But how to do the reverse process. To get the original time code from the resultant time code by subtracting the offset time code
The following function returns the difference between two date time values in words (as a string). Can it be written more efficiently/elegantly?
/**
* #hint Returns the difference between two time strings in words.
*/
public string function timeAgoInWords(required date fromTime, date toTime=now())
{
local.secondDiff = dateDiff("s", arguments.fromTime, arguments.toTime);
if (local.secondDiff <= 60)
return "#local.secondDiff# seconds ago";
local.minuteDiff = dateDiff("n", arguments.fromTime, arguments.toTime);
if (local.minuteDiff <= 60)
if (local.minuteDiff < 2)
return "1 minute ago";
else return "#local.minuteDiff# minutes ago";
if (local.minuteDiff <= 1440)
if (local.minuteDiff <= 120)
return "1 hour ago";
else return "#int(local.minuteDiff/60)# hours ago";
if (local.minuteDiff <= 2880)
return "yesterday";
if (local.minuteDiff <= 4320)
return "2 days ago";
local.monthDiff = dateDiff("m", arguments.fromTime, arguments.toTime);
if (local.monthDiff <= 12)
return "#dateFormat(arguments.fromTime, "mmm dd")# at #timeFormat(arguments.fromTime, "h:mm")#";
return "#dateFormat(arguments.fromTime, "mmm dd 'yy")# at #timeFormat(arguments.fromTime, "h:mm")#";
}
This is what I wrote a few months ago, based on the UDF Al Everett posted above in the comment and written in CF9 script style. It won't be more efficient. In fact, it should be slower then your implementation 'cause it has multiple calls to dateDiff(), and needs to set up 2 arrays up front, but the overall line count is shorter and easily understandable.
string function ago(required Date dateThen)
{
var dateparts = ["yyyy","m","d","h","n"];
var datepartNames = ["year","month","day","hour","minute"];
var rightNow = Now();
for (var i = 1; i <= 5; i++) // 5 == arrayLen(dateparts)
{
var diff = dateDiff(variables.dateparts[i], dateThen, rightNow);
if (diff > 1)
return "#diff# #datepartNames[i]#s ago";
if (diff == 1)
return "#diff# #datepartNames[i]# ago";
}
return "Just Now";
}
It looks good to me. You could instead use your first diff (local.secondDiff) for all your tests rather than re-diffing, but this is probably easier to read.