how to find weekdays from specific week in Flutter? - datetime

For example 20.week contain May 11, 2020 - May 17, 2020
The code have to show these date range. But the code shows : 2020-05-12 - 2020-05-18
Here's the code
DateTime getDateByWeekNumber({
int week,
int year,
bool start
}) {
DateTime date;
var days = ((week - 1) * 7) + (start ? 0: 6);
date = DateTime.utc(2020, 1, days);
return date;
}
Can someone help?

The ISO 8601 definition for week 01 is the week with the Gregorian year's first Thursday in it.
We need found out if first day of a year is before Thursday
DateTime getDateByWeekNumber({int week, int year, bool start}) {
DateTime startOfaYear = DateTime.utc(year, 1, 1);
int startOfaYearWeekDay = startOfaYear.weekday;
DateTime firstWeekOfaYear = startOfaYearWeekDay < 4
? startOfaYear.subtract(Duration(days: startOfaYearWeekDay - 1))
: startOfaYear.add(Duration(days: 8 - startOfaYearWeekDay));
DateTime startOfNWeek = firstWeekOfaYear.add(Duration(days: (week - 1) * 7));
return start ? startOfNWeek : startOfNWeek.add(Duration(days: 6));
}

This should work
DateTime getDateByWeekNumber({int week, int year, bool start}) {
DateTime date;
var days = ((week - 1) * 7) + (start ? -1 : 5);
date = DateTime.utc(2020, 1, days);
return date;
}

Related

Dart DateTime .difference

I want to set a timer to run once every minute, while I was writing the programm I found this unexpected behaviour
void main() {
final now = DateTime.now().toUtc();
final minuteAfterNow = new DateTime(now.year,now.month,now.day,now.hour,now.minute +1,now.second,now.millisecond,now.microsecond);
print(minuteAfterNow);
print(now);
print(minuteAfterNow.difference(now));
}
The output is the following:
2020-12-30 09:41:06.508
2020-12-30 09:40:06.508Z
-1:59:00.000000
Shouldn't the difference output 1 minute? What's with this output?
It is different because there are 2 issues:
1/ You are comparing between UTC and non UTC, that will take extra offset :). I will altenate you code and let you see by yourself:
final now = DateTime.now().toUtc();
final now1 = DateTime.utc(now.year, now.month, now.day,now.hour, now.minute, now.second + 1, now.millisecond, now.microsecond);
final difference = now.difference(now1);
print(difference);
2/ You missed the second, millisecond, microsecond parameters. Once you ignore it, it will be zero by default. Please take a look at the DateTime class in Dart
DateTime.utc(int year,
[int month = 1,
int day = 1,
int hour = 0,
int minute = 0,
int second = 0,
int millisecond = 0,
int microsecond = 0])
: this._internal(year, month, day, hour, minute, second, millisecond,
microsecond, true);
Btw, please add your code next time. Happy coding. :)
Yeah, I expected the difference function to calculate only the difference between two dates not checking if they are Utc or not which is not true
external DateTime._internal(int year, int month, int day, int hour,
int minute, int second, int millisecond, int microsecond, bool isUtc);
that is why the below code gives a desired output, even though the dates where the same before.
final now = DateTime.now();
final now2 = now.toUtc();
final minuteAfterNow = new DateTime(now.year,now.month,now.day,now.hour,now.minute +1,now.second,now.millisecond,now.microsecond).toUtc();
print(minuteAfterNow);
print(now2);
print(minuteAfterNow.difference(now2).inMinutes);
outputs:
2020-12-30 09:37:52.559Z
2020-12-30 09:36:52.559Z
1

How to get day of year, week of year from a DateTime Dart object

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.

specify current week based on day of week asp.net mvc 5

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);
}

How to find the day of a Date

I want to find the day of the week of a particular date in Qt.
e.g.: 1/05/2010 is Sunday.
Is it possible to find the weekday using date?
QDate date;
date.setDate(2010,5,1);
int day = date.dayOfWeek();
QString weekDay = QDate::longDayName(day);
This isn't tested. But hope it will work. Check it out and let know.
int QDate::dayOfWeek () const
Returns the weekday (1 to 7) for this date.
For example,
QDate date;
date.setDate(2010, 5, 1);
switch (date.dayOfWeek()) {
case 1:
// Monday
break;
// etc...
}
I think you want the QDate class and the dayOfWeek function.
int QDate::dayOfWeek () const
Returns the weekday (1 to 7) for this date.

Confused over some date/time calculations

So, I am trying to calculate the time between two dates that fits certain criteria (here: work / non-work) and I'm confused about the results as I can't find out why it's wrong.
But first, some code;
**Input Date A:** 2009-01-01 2:00 pm
**Input Date B:** 2009-01-02 9:00 am
So, as you can see, the total timespan (calculated e.g. by DateB.Substract(DateA)) is 19 hours.
I now want to calculate how many hours in this timespan are "non-work" hours, based on an average work day from 8am to 5pm - Result should be 15 hours (So, 19 - 15 = 4 hours total work time) (2:00 pm to 5:00 pm plus 8:00 am to 9:00 am)
But, following my code
DateTime _Temp = new DateTime(2009, 1, 1, 14, 0, 0);
DateTime _End = new DateTime(2009, 1, 2, 9, 0, 0);
int _WorkDayStart = 8;
int _WorkDayEnd = 17;
int _Return = 0;
while (_End > _Temp)
{
if (_Temp.Hour <= _WorkDayStart || _Temp.Hour >= _WorkDayEnd)
_Return++;
_Temp = _Temp.AddHours(1);
}
the result is 16 hours (19 - 16 = 3 hours total work time) - I don't see where the mistake is, so there is one hour missing?! I refactored it on paper and it should work as intended... but doesn't :-/
Anyone sees the mistake?
You're counting both ends as non-work, instead of just one. This line:
if (_Temp.Hour <= _WorkDayStart || _Temp.Hour >= _WorkDayEnd)
should probably be:
if (_Temp.Hour < _WorkDayStart || _Temp.Hour >= _WorkDayEnd)
You're effectively stepping through "start hours". So 8am itself should count as a work hour, because it's the start of a work hour, but 5pm won't because it's the start of a non-work hour.
I would also strongly advise you to either put braces around the body of the if statement or at least indent the following line. (I'd further advise you to use camelCase for local variables, but that's just a convention thing - I've never seen C# code written with that convention for local variables before now. You may want to read Microsoft's naming conventions document - it doesn't specify local variables, but they;re generally in camel case.)
Finally, I personally find it easier to read conditions where the "thing that's changing" is on the left - so I'd change your loop condition to:
while (_Temp < _End)
An alternative is to change it into a for loop. With all of these changes, the code would be:
DateTime start = new DateTime(2009, 1, 1, 14, 0, 0);
DateTime end = new DateTime(2009, 1, 2, 9, 0, 0);
int workDayStart = 8;
int workDayEnd = 17;
int nonWorkHours = 0;
for (DateTime time = start; time < end; time = time.AddHours(1))
{
if (time.Hour < workDayStart || time.Hour >= workDayEnd)
{
nonWorkHours++;
}
}
Finally, extract this into a method:
public static int CountNonWorkHours(DateTime start, DateTime end,
int workDayStart, int workDayEnd)
{
int nonWorkHours = 0;
for (DateTime time = start; time < end; time = time.AddHours(1))
{
if (time.Hour < workDayStart || time.Hour >= workDayEnd)
{
nonWorkHours++;
}
}
return nonWorkHours;
}
EDIT: Regarding konamiman's suggestion... yes, looping over each hour is very inefficient. However, it's relatively easy to get right. Unless you're going to be doing this a lot with long time periods, I'd use this fairly simple code. It would be very easy to end up with off-by-one errors in various situations if you tried to do a per-day version. While I don't like inefficient code, I don't mind it if it's not hurting me :)
If you plan to reuse this code, I would refactor it to avoid the loop. You could just multiply the number of whole days by the labour hours per day, then treat the first and the last day of the interval as special cases.
You could also use this to avoid a loop
DateTime startDate = new DateTime(2009, 1, 1, 14, 0, 0);
DateTime endDate = new DateTime(2009, 1, 2, 9, 0, 0);
int startTime = 8;
int endTime = 17;
int ret = ((endDate.Subtract(startDate).Days - 1) * 8)
+ (startDate.Hour >= startTime && startDate.Hour < endTime ? endTime - startDate.Hour : 0)
+ (endDate.Hour > startTime && endDate.Hour <= endTime ? endDate.Hour - startTime : 0);

Resources