check if datetime variable is today, tomorrow or yesterday - datetime

I do not know how to check if datetime variable is today, tomorrow or yesterday.
I did not find a method in the class members.

final now = DateTime.now();
final today = DateTime(now.year, now.month, now.day);
final yesterday = DateTime(now.year, now.month, now.day - 1);
final tomorrow = DateTime(now.year, now.month, now.day + 1);
final dateToCheck = ...
final aDate = DateTime(dateToCheck.year, dateToCheck.month, dateToCheck.day);
if(aDate == today) {
...
} else if(aDate == yesterday) {
...
} else(aDate == tomorrow) {
...
}
Hit: now.day - 1 and now.day + 1 works well with dates that result in a different year or month.

While the above answer is correct, I would like to provide a more compact and flexible alternative :
/// Returns the difference (in full days) between the provided date and today.
int calculateDifference(DateTime date) {
DateTime now = DateTime.now();
return DateTime(date.year, date.month, date.day).difference(DateTime(now.year, now.month, now.day)).inDays;
}
So if you want to check if date is :
Yesterday : calculateDifference(date) == -1.
Today : calculateDifference(date) == 0.
Tomorrow : calculateDifference(date) == 1.

Using dart extensions can help make your code more elegant. You can create a utility class with the following:
extension DateHelpers on DateTime {
bool isToday() {
final now = DateTime.now();
return now.day == this.day &&
now.month == this.month &&
now.year == this.year;
}
bool isYesterday() {
final yesterday = DateTime.now().subtract(Duration(days: 1));
return yesterday.day == this.day &&
yesterday.month == this.month &&
yesterday.year == this.year;
}
}
And then whenever you need to know if a day is today or yesterday, import the utility class into the file where you need it and then call the appropriate function like it was inbuilt in the DateTime class.
Text(
myDate.isToday() ? "Today"
: myDate.isYesterday() ? "Yesterday"
: DateFormat("dd MMM").format(myDate)
)

#34mo 's answer updated for flutter lint 2021
extension DateUtils on DateTime {
bool get isToday {
final now = DateTime.now();
return now.day == day && now.month == month && now.year == year;
}
bool get isTomorrow {
final tomorrow = DateTime.now().add(const Duration(days: 1));
return tomorrow.day == day &&
tomorrow.month == month &&
tomorrow.year == year;
}
bool get isYesterday {
final yesterday = DateTime.now().subtract(const Duration(days: 1));
return yesterday.day == day &&
yesterday.month == month &&
yesterday.year == year;
}
}

A simple isToday check:
/// Returns `true` if the [date] is today. Respects the time zone.
/// https://stackoverflow.com/a/60213219/1321917
bool isToday(DateTime date) {
final DateTime localDate = date.toLocal();
final now = DateTime.now();
final diff = now.difference(localDate).inDays;
return diff == 0 && now.day == localDate.day;
}

Simple method to check if is today
bool isToday(DateTime date) {
final now = DateTime.now();
return now.year == date.year &&
now.month == date.month &&
now.day == date.day;
}

For more simplification you can follow this steps.
String myDate = "01/09/2022";
like i need to check this "myDate" is today or tomorrow.
so,simply i call this function,
String dateConverter(String myDate) {
String date;
DateTime convertedDate =
DateFormat("DD/MM/YYYY").parse(myDate.toString());
final now = DateTime.now();
final today = DateTime(now.year, now.month, now.day);
final yesterday = DateTime(now.year, now.month, now.day - 1);
final tomorrow = DateTime(now.year, now.month, now.day + 1);
final dateToCheck = convertedDate;
final checkDate = DateTime(dateToCheck.year, dateToCheck.month, dateToCheck.day);
if (checkDate == today) {
date = "Today";
} else if (checkDate == yesterday) {
date = "Yesterday";
} else if (checkDate == tomorrow) {
date = "Tomorrow";
} else {
date = myDate;
}
return date;
}
if myDate is not today,tomorrow or yesterday then it simply return my default date string.

This one will also do the work
String checkDate(String dateString){
// example, dateString = "2020-01-26";
DateTime checkedTime= DateTime.parse(dateString);
DateTime currentTime= DateTime.now();
if((currentTime.year == checkedTime.year)
&& (currentTime.month == checkedTime.month)
&& (currentTime.day == checkedTime.day))
{
return "TODAY";
}
else if((currentTime.year == checkedTime.year)
&& (currentTime.month == checkedTime.month))
{
if((currentTime.day - checkedTime.day) == 1){
return "YESTERDAY";
}else if((currentTime.day - checkedTime.day) == -1){
return "TOMORROW";
}else{
return dateString;
}
}
}

Related

How to check if a given Date exists in DART?

If you pass a non-existing/non-real date like: '20181364' (2018/13/64) into DateTime (constructor or parse-method), no exception is thrown. Instead a calculated DateTime is returned.
Example:
'20181364' --> 2019-03-05 00:00:00.000
How can I check if a given date really exists/is valid?
I tried to solve this using DartPad (without success), so no Flutter doctor output required here.
void main() {
var inputs = ['20180101', // -> 2018-01-01 00:00:00.000
'20181231', // -> 2018-12-31 00:00:00.000
'20180230', // -> 2018-03-02 00:00:00.000
'20181301', // -> 2019-01-01 00:00:00.000
'20181364'];// -> 2019-03-05 00:00:00.000
inputs.forEach((input) => print(convertToDate(input)));
}
String convertToDate(String input){
return DateTime.parse(input).toString();
}
It would be great if there exist some kind of method to check if a given date really exists/is valid, e.g.:
a validate function in DateTime
another lib that does not use DateTime.parse() for validation
How would you solve this?
You can convert parsed date to string with original format and then compare if it's matching the input.
void main() {
var inputs = ['20180101', // -> 2018-01-01 00:00:00.000
'20181231', // -> 2018-12-31 00:00:00.000
'20180230', // -> 2018-03-02 00:00:00.000
'20181301', // -> 2019-01-01 00:00:00.000
'20181364'];// -> 2019-03-05 00:00:00.000
inputs.forEach((input) {
print("$input is valid string: ${isValidDate(input)}");
});
}
bool isValidDate(String input) {
final date = DateTime.parse(input);
final originalFormatString = toOriginalFormatString(date);
return input == originalFormatString;
}
String toOriginalFormatString(DateTime dateTime) {
final y = dateTime.year.toString().padLeft(4, '0');
final m = dateTime.month.toString().padLeft(2, '0');
final d = dateTime.day.toString().padLeft(2, '0');
return "$y$m$d";
}
My solution to validate the birthday was this, we can see that it has the leap year calculation.
class DateHelper{
/*
* Is valid date and format
*
* Format: dd/MM/yyyy
* valid:
* 01/12/1996
* invalid:
* 01/13/1996
*
* Format: MM/dd/yyyy
* valid:
* 12/01/1996
* invalid
* 13/01/1996
* */
static bool isValidDateBirth(String date, String format) {
try {
int day, month, year;
//Get separator data 10/10/2020, 2020-10-10, 10.10.2020
String separator = RegExp("([-/.])").firstMatch(date).group(0)[0];
//Split by separator [mm, dd, yyyy]
var frSplit = format.split(separator);
//Split by separtor [10, 10, 2020]
var dtSplit = date.split(separator);
for (int i = 0; i < frSplit.length; i++) {
var frm = frSplit[i].toLowerCase();
var vl = dtSplit[i];
if (frm == "dd")
day = int.parse(vl);
else if (frm == "mm")
month = int.parse(vl);
else if (frm == "yyyy")
year = int.parse(vl);
}
//First date check
//The dart does not throw an exception for invalid date.
var now = DateTime.now();
if(month > 12 || month < 1 || day < 1 || day > daysInMonth(month, year) || year < 1810 || (year > now.year && day > now.day && month > now.month))
throw Exception("Date birth invalid.");
return true;
} catch (e) {
return false;
}
}
static int daysInMonth(int month, int year) {
int days = 28 + (month + (month/8).floor()) % 2 + 2 % month + 2 * (1/month).floor();
return (isLeapYear(year) && month == 2)? 29 : days;
}
static bool isLeapYear(int year)
=> (( year % 4 == 0 && year % 100 != 0 ) || year % 400 == 0 );
}
Support for validating dates was added for dart in December 2020: https://pub.dev/documentation/intl/latest/intl/DateFormat/parseStrict.html

getting an int to decrement after an action

so in my person table...I have Id, Name & HolidaysRemaining.
Its for a holiday booking application, and atm when a user selects dates from a calendar and clicks the button, each date selected will be stored in the DB, I am trying to minus the holidays remaining by 1, as each holiday is booked, but it doesn't seem to be picking up.
//listHolidays in correct format dd/mm/yy
[HttpPost]
public ActionResult listHolidays(Holiday holiday, Person person , int? PersonId, string HolidayDate, string endDate, string AlreadyExists)
{
db.People.Attach(person);
//int holidaysRemaining = 20;
//person.HolidaysRemaining = holidaysRemaining;
DateTime startDates = Convert.ToDateTime(HolidayDate);
DateTime endDates = Convert.ToDateTime(endDate);
try{
while (startDates <= endDates)
{
if (startDates.DayOfWeek != DayOfWeek.Saturday && startDates.DayOfWeek != DayOfWeek.Sunday)
{
//if user selects Holiday that already exists, wont add it to Db
//gets string, and uses the previously converted to dateTime 'startDate'
//id so only applies to person creating holidays
ViewBag.CantDuplicateHolidays = String.IsNullOrEmpty(AlreadyExists) ? "date" : "";
var dates = from d in db.Holidays
where d.HolidayDate == startDates && d.PersonId == PersonId
select d;
// <= 0..so if holiday does not already exist
if (dates.Count() <= 0)
{
// holidaysRemaining--;
person.HolidaysRemaining = person.HolidaysRemaining - 1;
Holiday holiday1 = new Holiday();
holiday1.PersonId = PersonId.Value;
holiday1.HolidayDate = startDates;
db.Holidays.AddObject(holiday1);
db.SaveChanges();
//say start date is 10. AddDays(1) will make it 11 then return it to startDates in 'startDates' = startdates,
//but doesnt chage the value of startdates = 'startdates'
}
}
}
startDates = startDates.AddDays(1);
}
finally
{
db.People.Detach();
}
return RedirectToAction("Index");
}
Probably this is the easiest solution.
replace:
person.HolidaysRemaining = person.HolidaysRemaining - 1;
with:
var dbPerson = from p in db.People where p.Id == PersonId select p;
dbPerson[0].HolidaysRemaining--;
Alternatively we were discussing attaching the person object since you have it:
db.People.Attach(person)
try {
// ... loop and everything else here
} finally {
db.People.Detach(person);
}
} // end of method
But this is a bit more brittle, and would only be necessary if there's not already a Person object in db.People.
Note: It seems a little weird that both person and PersonId are passed into listHolidays().
I think your problem is here:
if (dates.Count() <= 0)
{
// holidaysRemaining--;
person.HolidaysRemaining--;
Try changing it to:
if (dates.Count() <= 0)
{
// holidaysRemaining--;
person.HolidaysRemaining = person.HolidaysRemaining - 1;
EDIT
Also, you never actually update the database with person?
db.People.Attach(person);
before db.SaveChanges();
EDIT AGAIN
Try this:
[HttpPost]
public ActionResult listHolidays(Holiday holiday, Person person, int? PersonId, string HolidayDate, string endDate, string AlreadyExists)
{
//int holidaysRemaining = 20;
//person.HolidaysRemaining = holidaysRemaining;
DateTime startDates = Convert.ToDateTime(HolidayDate);
DateTime endDates = Convert.ToDateTime(endDate);
while (startDates <= endDates)
{
if (startDates.DayOfWeek != DayOfWeek.Saturday && startDates.DayOfWeek != DayOfWeek.Sunday)
{
//if user selects Holiday that already exists, wont add it to Db
//gets string, and uses the previously converted to dateTime 'startDate'
//id so only applies to person creating holidays
ViewBag.CantDuplicateHolidays = String.IsNullOrEmpty(AlreadyExists) ? "date" : "";
var dates = from d in db.Holidays
where d.HolidayDate == startDates && d.PersonId == PersonId
select d;
// <= 0..so if holiday does not already exist
if (dates.Count() <= 0)
{
// holidaysRemaining--;
person.HolidaysRemaining = person.HolidaysRemaining - 1;
Holiday holiday1 = new Holiday();
holiday1.PersonId = PersonId.Value;
holiday1.HolidayDate = startDates;
db.Holidays.AddObject(holiday1);
db.People.Attach(person);
db.SaveChanges();
//say start date is 10. AddDays(1) will make it 11 then return it to startDates in 'startDates' = startdates,
//but doesnt chage the value of startdates = 'startdates'
}
}
startDates = startDates.AddDays(1);
}
return RedirectToAction("Index");
}

Verify a date in JavaScript

I need to do user validation of a date field, it should be in the format yyyyMMdd and should not be more than one year in the future. How would I go about doing this? Currently I only have a crude regexp which is insufficient.
function VerifyDate(source, args)
{
var regexp = /^([1-2]{1}[0-9]{1})\d{2}([0][1-9]|[1][0-2])([0][1-9]|[1-2][0-9]|[3][0-1])$/
var result = args.Value.match(regexp);
if(result) {
args.IsValid = true;
} else {
args.IsValid = false;
}
}
Take the regex to check the format only. You can stay simple:
^(\d{4})(\d{2})(\d{2})$
Then parse the date and check the range:
function VerifyDate(source, args)
{
args.IsValid = false;
var regexp = /^(\d{4})(\d{2})(\d{2})$/;
var daysInMonth = function (y, m) {return 32-new Date(y, m, 32).getDate(); };
var ma = regexp.exec(args.Value);
if (ma && ma.length == 4 && ma[2] < 12 && ma[3] <= daysInMonth(ma[1], ma[2]))
{
var diff = new Date(ma[1], ma[2], ma[3]) - new Date();
args.IsValid = diff < 31536000000; // one year = 1000ms*60*60*24*365
}
}
new Date() don't throw an exception if month or day is out of range. It uses the internal MakeDay to calculate a date (see ECMAScript Language Specification section 15.9.3.1 and 15.9.1.13). To make sure that the date is valid in the function below, the input is converted to integers who is converted to a date, and then the parts of the date are compared to the integers.
Since date uses MakeDay, the calculation of maxDate works even if now is the leep day (xxxx0229 will be yyyy0301 where yyyy=xxxx+1)
function verifyDate(args)
{
var result=false,
match = args.Value.match(/^(\d{4})(\d{2})(\d{2})$/);
if (match && match.length === 4)
{
var year = parseInt(match[1],10),
month =parseInt(match[2],10) -1, // 0 = January
day = parseInt(match[3],10),
testDate= new Date(year,month,day),
now = new Date(),
maxDate = new Date(now.getFullYear() + 1, now.getMonth(), now. getDate()),
minDate = new Date(1800,0,1),
result = (
testDate.getFullYear() === year &&
testDate.getMonth() === month &&
testDate.getDate() === day &&
testDate >= minDate &&
testDate <= maxDate
);
}
args.IsValue = result;
return result;
}
The solution I finally went with is a combination of your answers, I used datejs which seems pretty nice. Here is my final validation function. For some reason the month seems to use a 0 based index so that's why it says -1 in the .set().
function VerifyDate(source, args)
{
args.IsValid = false;
var regexp = /^(\d{4})(\d{2})(\d{2})$/;
var m = regexp.exec(args.Value);
if (m && m.length == 4) {
try {
var result = Date.today().set({ year: Number(m[1]), month: Number(m[2]-1), day: Number(m[3]) });
if (result < Date.today().add({ years: 1 })) {
args.IsValid = true;
}
}
catch (ex) {
}
}
}

Best Way To Get All Dates Between DateA and DateB

I am using an asp:Calander and I have an object that has a beginning date and an ending date. I need to get all the dates between these two dates and place them in an array so i can then render corresponding dates on the calander with different CSS
DateTime startDate;
DateTime endDate;
DateTime currentDate = startDate;
List<DateTime> dates = new List<DateTime> ();
while (true)
{
dates.Add (currentDate);
if (currentDate.Equals (endDate)) break;
currentDate = currentDate.AddDays (1);
}
It assumes that startDate < than endDate, you get the results on the "dates" list
IEnumerable<DateTime> RangeDays(DateTime RangeStart, DateTime RangeEnd) {
DateTime EndDate = RangeEnd.Date;
for (DateTime WorkDate = RangeStart.Date; WorkDate <= EndDate; WorkDate = WorkDate.AddDays(1)) {
yield return WorkDate;
}
yield break;
}
Untested code... but should work.
I voted up AlbertEin because he gave a good answer, but do you really need a collection to hold all the dates? When you are rendering the day, couldn't you just check if the date is withing the specified range, and then render it differently, no need for a collection. Here's some code to demonstrate
DateTime RangeStartDate,RangeEndDate; //Init as necessary
DateTime CalendarStartDate,CalendarEndDate; //Init as necessary
DateTime CurrentDate = CalendarStartDate;
String CSSClass;
while (CurrentDate != CalendarEndDate)
{
if(CurrentDate >= RangeStartDate && CurrentDate <= RangeEndDate)
{
CSSClass= "InRange";
}
else
{
CSSClass = "OutOfRange";
}
//Code For rendering calendar goes here
currentDate = currentDate.AddDays (1);
}
// inclusive
var allDates = Enumerable.Range(0, (endDate - startDate).Days + 1).Select(i => startDate.AddDays(i));
// exclusive
var allDates = Enumerable.Range(1, (endDate - startDate).Days).Select(i => startDate.AddDays(i));

Actionscript 3 - Fastest way to parse yyyy-mm-dd hh:mm:ss to a Date object?

I have been trying to find a really fast way to parse yyyy-mm-dd [hh:mm:ss] into a Date object. Here are the 3 ways I have tried doing it and the times it takes each method to parse 50,000 date time strings.
Does anyone know any faster ways of doing this or tips to speed up the methods?
castMethod1 takes 3673 ms
castMethod2 takes 3812 ms
castMethod3 takes 3931 ms
Code:
private function castMethod1(dateString:String):Date {
if ( dateString == null ) {
return null;
}
var year:int = int(dateString.substr(0,4));
var month:int = int(dateString.substr(5,2))-1;
var day:int = int(dateString.substr(8,2));
if ( year == 0 && month == 0 && day == 0 ) {
return null;
}
if ( dateString.length == 10 ) {
return new Date(year, month, day);
}
var hour:int = int(dateString.substr(11,2));
var minute:int = int(dateString.substr(14,2));
var second:int = int(dateString.substr(17,2));
return new Date(year, month, day, hour, minute, second);
}
-
private function castMethod2(dateString:String):Date {
if ( dateString == null ) {
return null;
}
if ( dateString.indexOf("0000-00-00") != -1 ) {
return null;
}
dateString = dateString.split("-").join("/");
return new Date(Date.parse( dateString ));
}
-
private function castMethod3(dateString:String):Date {
if ( dateString == null ) {
return null;
}
var mainParts:Array = dateString.split(" ");
var dateParts:Array = mainParts[0].split("-");
if ( Number(dateParts[0])+Number(dateParts[1])+Number(dateParts[2]) == 0 ) {
return null;
}
return new Date( Date.parse( dateParts.join("/")+(mainParts[1]?" "+mainParts[1]:" ") ) );
}
No, Date.parse will not handle dashes by default. And I need to return null for date time strings like "0000-00-00".
I've been using the following snipplet to parse UTC date strings:
private function parseUTCDate( str : String ) : Date {
var matches : Array = str.match(/(\d\d\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)Z/);
var d : Date = new Date();
d.setUTCFullYear(int(matches[1]), int(matches[2]) - 1, int(matches[3]));
d.setUTCHours(int(matches[4]), int(matches[5]), int(matches[6]), 0);
return d;
}
Just remove the time part and it should work fine for your needs:
private function parseDate( str : String ) : Date {
var matches : Array = str.match(/(\d\d\d\d)-(\d\d)-(\d\d)/);
var d : Date = new Date();
d.setUTCFullYear(int(matches[1]), int(matches[2]) - 1, int(matches[3]));
return d;
}
No idea about the speed, I haven't been worried about that in my applications. 50K iterations in significantly less than a second on my machine.
This was the fastest I could come up with after some fiddling:
private function castMethod4(dateString:String):Date {
if ( dateString == null )
return null;
if ( dateString.length != 10 && dateString.length != 19)
return null;
dateString = dateString.replace("-", "/");
dateString = dateString.replace("-", "/");
return new Date(Date.parse( dateString ));
}
I get 50k iterations in about 470ms for castMethod2() on my computer and 300 ms for my version (that's the same amount of work done in 63% of the time). I'd definitely say both are "Good enough" unless you're parsing silly amounts of dates.
I'm guessing Date.Parse() doesn't work?
Well then method 2 seems the best way:
private function castMethod2(dateString:String):Date {
if ( dateString == null ) {
return null;
}
if ( dateString.indexOf("0000-00-00") != -1 ) {
return null;
}
dateString = dateString.split("-").join("/");
return new Date(Date.parse( dateString ));
}
Because Date.parse() does not accept all possible formats, we can preformat the passed dateString value using DateFormatter with formatString that Data.parse() can understand, e.g
// English formatter
var stringValue = "2010.10.06"
var dateCommonFormatter : DateFormatter = new DateFormatter();
dateCommonFormatter.formatString = "YYYY/MM/DD";
var formattedStringValue : String = dateCommonFormatter.format(stringValue);
var dateFromString : Date = new Date(Date.parse(formattedStringValue));
var strDate:String = "2013-01-24 01:02:40";
function dateParser(s:String):Date{
var regexp:RegExp = /(\d{4})\-(\d{1,2})\-(\d{1,2}) (\d{2})\:(\d{2})\:(\d{2})/;
var _result:Object = regexp.exec(s);
return new Date(
parseInt(_result[1]),
parseInt(_result[2])-1,
parseInt(_result[3]),
parseInt(_result[4]),
parseInt(_result[5]),
parseInt(_result[6])
);
}
var myDate:Date = dateParser(strDate);
Here is my implementation. Give this a try.
public static function dateToUtcTime(date:Date):String {
var tmp:Array = new Array();
var char:String;
var output:String = '';
// create format YYMMDDhhmmssZ
// ensure 2 digits are used for each format entry, so 0x00 suffuxed at each byte
tmp.push(date.secondsUTC);
tmp.push(date.minutesUTC);
tmp.push(date.hoursUTC);
tmp.push(date.getUTCDate());
tmp.push(date.getUTCMonth() + 1); // months 0-11
tmp.push(date.getUTCFullYear() % 100);
for(var i:int=0; i < 6/* 7 items pushed*/; ++i) {
char = String(tmp.pop());
trace("char: " + char);
if(char.length < 2)
output += "0";
output += char;
}
output += 'Z';
return output;
}

Resources