Flutter: Get Wrong days of the week - flutter

from Monday - Thursday, I get the right days, but from Friday, I get the wrong days. Why?
Code example:
Text(DateFormat('EEEE').format(DateTime(DateTime.friday))),
And i get Saturday. Is that a bug?

It's not a bug, DateTime() default constructor takes year as the first argument:
DateTime(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, false);
So this code:
DateTime date = DateTime(DateTime.friday);
Is essentially constructing a DateTime of the year 5, because DateTime.friday is nothing more than a const int that equals to 5:
static const int monday = 1;
static const int tuesday = 2;
static const int wednesday = 3;
static const int thursday = 4;
static const int friday = 5;
static const int saturday = 6;
static const int sunday = 7;
static const int daysPerWeek = 7;
Formatting with DateFormat returns Saturday which happens to be the first day of the year:
import 'dart:core';
import 'package:intl/intl.dart';
main() {
DateTime date = DateTime(DateTime.friday); // creates a DateTime of the year 5
print(date.year); // year: 5
print(date.month); // month: Jan (default = 1)
print(date.weekday); // day: Saturday (first day of the year)
print("${date.year}-${date.month}-${date.day}"); // 5-1-1
}
DateTime should be used to define a specific Date and Time, for example, Friday 11th Dec 2020, it can't be used to define any Friday.

Related

Flutter how to get dates from week number

I am trying to get dates from week number in flutter. But I dont know how to do it. I got the week number and the days of the week. Now I want to get the dates from the days in this week.
For example:
week 2 Monday date,
week 2 Tuesday date,
week 2 Friday date
I have started with this code but I need to solve it in another way.
int weeknumber = 2;
//1=monday, 2=tuesday, 5=friday
List<int> weekdays = [1,2,5];
int year = 2023;
int totaldays = weeknumber * 7;
final extraDuration = Duration(days: totaldays);
final startDate = DateTime(year);
final dates = startDate.add(extraDuration);
print(dates);
Here is the output: 2023-01-15 00:00:00.000
But I want: 2023-01-09, 2023-01-10, 2023-01-13
What can I do to get these dates?
If you want this output
Monday:2023-01-09 00:00:00.000
Tuesday:2023-01-10 00:00:00.000
Friday:2023-01-13 00:00:00.000
you can work on this code
import 'package:intl/intl.dart';
void main() {
int weeknumber = 2;
//1=monday, 2=tuesday, 5=friday
List<String> weekdays = ['Monday','Tuesday','Friday'];
int year = 2023;
int firstDayOfWeek = (weeknumber-1) * 7;
final extraDuration = Duration(days: firstDayOfWeek);
final startDate = DateTime(year);
final dates = startDate.add(extraDuration);
for (var i = 0; i < 7; i++) {
var newDate = dates.add(Duration(days: i));
if(DateFormat('EEEE').format(newDate) == 'Monday')print('Monday:'+newDate.toString());
else if(DateFormat('EEEE').format(newDate) == 'Tuesday')print('Tuesday:'+newDate.toString());
else if(DateFormat('EEEE').format(newDate) == 'Friday')print('Friday:'+newDate.toString());
}
print(dates);
}

how to create a 30 minutes timeslot.. Im getting the start date and end date from backend

List<WorkingHourModel> workingHours = response['hours'];
int startTime = int.parse(workingHours[0].startTime.split(':')[0]);
int endTime = int.parse(workingHours[0].endTime.split(':')[0]);
int hoursLeft = endTime - startTime + 1;
List<String> hours =
List.generate(hoursLeft, (i) => '${(endTime - i)}:00').reversed
.toList();
print('Hours-------- $hours');
return {
'success': true,
'hours': hours,
};
}
//this will give the time slots as '1:00', '2:00', '3:00', '4:00'
//Start time will be 1:00 and end time will be 4:00.
Heading
But i need 30 mins breakage, like,
'1:00', '1:30', '2:00', '2:30', '3:00', '3:30', '4:00'
Kindly help..
This should generate the list as you want it:
void main(List<String> args) {
// lets assume 9 to 5
int startTime = 9;
int endTime = 17;
int hoursLeft = endTime - startTime + 1;
final hours = List.generate(hoursLeft * 2, (i) => '${endTime - (i/2).truncate()}:${i%2 == 1 ? '00' : '30'}').reversed.toList();
print('Hours-------- $hours');
}
Hours-------- [9:00, 9:30, 10:00, 10:30, 11:00, 11:30, 12:00, 12:30, 13:00, 13:30, 14:00, 14:30, 15:00, 15:30, 16:00, 16:30, 17:00, 17:30]
Generally speaking, if you have more complicated calculations (what happens if someone works 18:00 to 05:00 in the nightshift?) you may want to use the proper datatypes instead of integers and string concatenation.

Flutter: Find the number of days between two dates

I currently have a user's profile page that brings out their date of birth and other details. But I am planning to find the days before their birthday by calculating the difference between today's date and the date of birth obtained from the user.
User's Date of Birth
And this is today's date obtained by using the intl package.
Today's date
I/flutter ( 5557): 09-10-2018
The problem I am facing now is, How do I calculate the difference in days of these two dates?
Are there any specific formulas or packages that are available for me to check out?
You can use the difference method provide by DateTime class
//the birthday's date
final birthday = DateTime(1967, 10, 12);
final date2 = DateTime.now();
final difference = date2.difference(birthday).inDays;
UPDATE
Since many of you reported there is a bug with this solution and to avoid more mistakes, I'll add here the correct solution made by #MarcG, all the credits to him.
int daysBetween(DateTime from, DateTime to) {
from = DateTime(from.year, from.month, from.day);
to = DateTime(to.year, to.month, to.day);
return (to.difference(from).inHours / 24).round();
}
//the birthday's date
final birthday = DateTime(1967, 10, 12);
final date2 = DateTime.now();
final difference = daysBetween(birthday, date2);
This is the original answer with full explanation: https://stackoverflow.com/a/67679455/666221
The accepted answer is wrong. Don't use it.
This is correct:
int daysBetween(DateTime from, DateTime to) {
from = DateTime(from.year, from.month, from.day);
to = DateTime(to.year, to.month, to.day);
return (to.difference(from).inHours / 24).round();
}
Testing:
DateTime date1 = DateTime.parse("2020-01-09 23:00:00.299871");
DateTime date2 = DateTime.parse("2020-01-10 00:00:00.299871");
expect(daysBetween(date1, date2), 1); // Works!
Explanation why the accepted answer is wrong:
Just run this:
int daysBetween_wrong1(DateTime date1, DateTime date2) {
return date1.difference(date2).inDays;
}
DateTime date1 = DateTime.parse("2020-01-09 23:00:00.299871");
DateTime date2 = DateTime.parse("2020-01-10 00:00:00.299871");
// Should return 1, but returns 0.
expect(daysBetween_wrong1(date1, date2), 0);
Note: Because of daylight savings, you can have a 23 hours difference between some day and the next day, even if you normalize to 0:00. That's why the following is ALSO incorrect:
// Fails, for example, when date2 was moved 1 hour before because of daylight savings.
int daysBetween_wrong2(DateTime date1, DateTime date2) {
from = DateTime(date1.year, date1.month, date1.day);
to = DateTime(date2.year, date2.month, date2.day);
return date2.difference(date1).inDays;
}
Rant: If you ask me, Dart DateTime is very bad. It should at least have basic stuff like daysBetween and also timezone treatment etc.
Update: The package https://pub.dev/packages/time_machine claims to be a port of Noda Time. If that's the case, and it's ported correctly (I haven't tested it yet) then that's the Date/Time package you should probably use.
Use 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');
or
You can use jiffy. Jiffy is a date dart package inspired by momentjs for parsing, manipulating and formatting dates.
Example:
1. Relative Time
Jiffy("2011-10-31", "yyyy-MM-dd").fromNow(); // 8 years ago
Jiffy("2012-06-20").fromNow(); // 7 years ago
var jiffy1 = Jiffy()
..startOf(Units.DAY);
jiffy1.fromNow(); // 19 hours ago
var jiffy2 = Jiffy()
..endOf(Units.DAY);
jiffy2.fromNow(); // in 5 hours
var jiffy3 = Jiffy()
..startOf(Units.HOUR);
jiffy3.fromNow();
2. Date Manipulation:
var jiffy1 = Jiffy()
..add(duration: Duration(days: 1));
jiffy1.yMMMMd; // October 20, 2019
var jiffy2 = Jiffy()
..subtract(days: 1);
jiffy2.yMMMMd; // October 18, 2019
// You can chain methods by using Dart method cascading
var jiffy3 = Jiffy()
..add(hours: 3, days: 1)
..subtract(minutes: 30, months: 1);
jiffy3.yMMMMEEEEdjm; // Friday, September 20, 2019 9:50 PM
var jiffy4 = Jiffy()
..add(duration: Duration(days: 1, hours: 3))
..subtract(duration: Duration(minutes: 30));
jiffy4.format("dd/MM/yyy"); // 20/10/2019
// Months and year are added in respect to how many
// days there are in a months and if is a year is a leap year
Jiffy("2010/1/31", "yyyy-MM-dd"); // This is January 31
Jiffy([2010, 1, 31]).add(months: 1); // This is February 28
You can Use the Datetime class to find the difference between the two years without using intl to format the date.
DateTime dob = DateTime.parse('1967-10-12');
Duration dur = DateTime.now().difference(dob);
String differenceInYears = (dur.inDays/365).floor().toString();
return new Text(differenceInYears + ' years');
Naively subtracting one DateTime from another with DateTime.difference is subtly wrong. As explained by 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.
Instead of rounding the computed number of days, you can ignore Daylight Saving Time in DateTime calculations by using UTC DateTime objects1 because UTC does not observe DST.
Therefore, to compute the difference in days between two dates, ignoring the time (and also ignoring Daylight Saving adjustments and time zones), construct new UTC DateTime objects with the same dates and that use the same time of day:
/// Returns the number of calendar days between [later] and [earlier], ignoring
/// time of day.
///
/// Returns a positive number if [later] occurs after [earlier].
int differenceInCalendarDays(DateTime later, DateTime earlier) {
// Normalize [DateTime] objects to UTC and to discard time information.
later = DateTime.utc(later.year, later.month, later.day);
earlier = DateTime.utc(earlier.year, earlier.month, earlier.day);
return later.difference(earlier).inDays;
}
Update
I've added a calendarDaysTill extension method to package:basics that can do this.
1 Be aware that converting a local DateTime object to UTC with .toUtc() will not help; dateTime and dateTime.toUtc() both represent the same moment in time, so dateTime1.difference(dateTime2) and dateTime1.toUtc().difference(dateTime.toUtc()) would return the same Duration.
If anyone wants to find out the difference in form of seconds, minutes, hours, and days. Then here is my approach.
static String calculateTimeDifferenceBetween(
{#required DateTime startDate, #required DateTime endDate}) {
int seconds = endDate.difference(startDate).inSeconds;
if (seconds < 60)
return '$seconds second';
else if (seconds >= 60 && seconds < 3600)
return '${startDate.difference(endDate).inMinutes.abs()} minute';
else if (seconds >= 3600 && seconds < 86400)
return '${startDate.difference(endDate).inHours} hour';
else
return '${startDate.difference(endDate).inDays} day';
}
Beware of future "bugs" with selected answer
Something really missing in the selected answer - massively upvoted oddly - is that it will calculate the difference between two dates in term of:
Duration
It means that if there is less than 24h of differences both dates will be considered to be the same!! Often it is not the desired behavior. You can fix this by tweaking slightly the code in order to truncate from the day the clock:
Datetime from = DateTime(1987, 07, 11); // this one does not need to be converted, in this specific example, but we assume that the time was included in the datetime.
Datetime to = DateTime.now();
print(daysElapsedSince(from, to));
[...]
int daysElapsedSince(DateTime from, DateTime to) {
// get the difference in term of days, and not just a 24h difference
from = DateTime(from.year, from.month, from.day);
to = DateTime(to.year, to.month, to.day);
return to.difference(from).inDays;
}
You can hence detect if from was before to, as it will return a positive integer representing the difference in term of number of days, else negative, and 0 if both happened on same day.
It is indicated in the documentation what this function return and in many usecases it can lead to some problem that may be difficult to debug if following the original selected answer:
Returns a Duration with the difference when subtracting other (from) from this (to).
Hope it helps.
void main() {
DateTime dt1 = DateTime.parse("2021-12-23 11:47:00");
DateTime dt2 = DateTime.parse("2018-09-12 10:57:00");
Duration diff = dt1.difference(dt2);
print(diff.inDays);
//output (in days): 1198
print(diff.inHours);
//output (in hours): 28752
}
Simplest solution:
// d2.difference(d1).inDays
void main() {
final d1 = DateTime.now();
final d2 = d1.add(Duration(days: 2));
print(d2.difference(d1).inDays);
}
Check it out on DartPad example
Another and maybe more intuitive option is to use Basics package:
// the birthday's date
final birthday = DateTime(1967, 10, 12);
final today = DateTime.now();
final difference = (today - birthday).inDays;
For more information about the package: https://pub.dev/packages/basics
All of these answers miss a crucial part and that is leap year.
Here is the perfect solution for calculating age:
calculateAge(DateTime birthDate) {
DateTime currentDate = DateTime.now();
int age = currentDate.year - birthDate.year;
int month1 = currentDate.month;
int month2 = birthDate.month;
if (month2 > month1) {
age--;
} else if (month1 == month2) {
int day1 = currentDate.day;
int day2 = birthDate.day;
if (day2 > day1) {
age--;
}
}
return age;
}
The above answers are also correct, I just create a single method to find out the difference between the two days, accepted for the current day.
void differenceBetweenDays() {
final date1 = DateTime(2022, 01, 01); // 01 jan 2022
final date2 = DateTime(2022, 02, 01); // 01 feb 2022
final currentDay = DateTime.now(); // Current date
final differenceFormTwoDates = daysDifferenceBetween(date1, date2);
final differenceFormCurrent = daysDifferenceBetween(date1, currentDay);
print("difference From date1 and date 2 :- "+differenceFormTwoDates.toString()+" "+"Days");
print("difference From date1 and Today :- "+differenceFormCurrent.toString()+" "+"Days");
}
int daysDifferenceBetween(DateTime from, DateTime to) {
from = DateTime(from.year, from.month, from.day);
to = DateTime(to.year, to.month, to.day);
return (to.difference(from).inHours / 24).round();
}
var start_date = "${DateTime.now()}";
var fulldate =start_date.split(" ")[0].split("-");
var year1 = int.parse(fulldate[0]);
var mon1 = int.parse(fulldate[1]);
var day1 = int.parse(fulldate[2]);
var date1 = (DateTime(year1,mon1,day1).millisecondsSinceEpoch);
var date2 = DateTime(2021,05,2).millisecondsSinceEpoch;
var Difference_In_Time = date2 - date1;
var Difference_In_Days = Difference_In_Time / (1000 * 3600 * 24);
print(Difference_In_Days); ```
Extension on DateTime
With an extension class you could:
int days = birthdate.daysSince;
Example extension class:
extension DateTimeExt on DateTime {
int get daysSince => this.difference(DateTime.now()).inDays;
}

Convert time/date to epoch (seconds since 1970)

I'm trying to write a function to convert a time & date into epoch seconds, it's for a small system that doesn't have the usual time_t library functions. I've got this code below but the calculation is a bit off, can anyone see what's wrong?
long getSecondsSinceEpoch(int h, int m, int s, int day, int month, int year) {
int i,leapDays;
long days;
long seconds;
const static DAYS_IN_MONTH[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
leapDays = 0;
days = (year - 1970) * 365;
for (i = year; i>1970; i--){
if ((i%4)==0) {
leapDays++;
}
}
days += leapDays;
for (i = 1;i < month;i++) {
days += DAYS_IN_MONTH[i - 1];
}
days += day;
seconds = days * 86400;
seconds += (h * 3600);
seconds += (m * 60);
seconds += s;
return seconds;
}
One error is maybe, that you don't take into consideration if you are before February 29th or not when adding the leap days. But I am not sure if this is the only mistake.
EDIT: I think I found the second error: You add all day to days. You should add day - 1 to days, as 08:00 of January 1st is only 8 hours from the start of the month and not 24+8 hours from it.

Can this be done using LINQ/Lambda, C#3.0

Objective: Generate dates based on Week Numbers
Input: StartDate, WeekNumber
Output: List of dates from the Week number specified till the StartDate
i.e. If startdate is 23rd April, 2010 and the week number is 1, then the program should return the dates from 16th April, 2010 till the startddate.
The function
public List<DateTime> GetDates(DateTime startDate,int weeks)
{
List<DateTime> dt = new List<DateTime>();
int days = weeks * 7;
DateTime endDate = startDate.AddDays(-days);
TimeSpan ts = startDate.Subtract(endDate);
for (int i = 0; i <= ts.Days; i++)
{
DateTime dt1 = endDate.AddDays(i);
dt.Add(dt1);
}
return dt;
}
I am calling this function as
DateTime StartDate = DateTime.ParseExact("20100423", "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture);
List<DateTime> dtList = GetDates(StartDate, 1);
The program is working fine.
Question is using C# 3.0 feature like Linq, Lambda etc. can I rewrite the program.
Why? Because I am learning linq and lambda and want to implement the same. But as of now the knowledge is not sufficient to do the same by myself.
Thanks.
Something like this:
public IEnumerable<DateTime> GetDates2(DateTime startDate, int weeks)
{
var days = weeks * 7;
return Enumerable.Range(-days, days + 1).Select(i => startDate.AddDays(i));
}
The Enumerable.Range method will return a sequence of integers within a specified range, in your example from -7 to 0.
After that I simply use each integer to substract that number of days from your initial startDate, building an IEnumerable<DateTime>.
You can try something like
int weeks = 1;
var days = from d in Enumerable.Range(-weeks * 7, weeks * 7 + 1)
select StartDate.AddDays(d);