Groovy : Find the date of the previous Monday - date

In the following code, i want to find the date of the last Monday.
For that, i have two variable :
startDay = today - 7 days
stopDay = today - 1 day (yesterday)
And i have a function that list all dates between "startDay" and "stopDay", and search in these dates, which one corresponds to Monday.
It works well when i have two dates in the same ten :
startDay = 2014-07-20
stopDay = 2014-07-29
But, when one of both change decade, the code end with an error:
startDay = 2014-07-29
stopDay = 2014-07-30
ERROR:
java.lang.IllegalArgumentException: Incompatible Strings for Range: String#next() will not reach the expected value
CODE:
def searchDay = { start, stop -> (start..stop).findAll { Date.parse("yyyy-MM-dd", "${it}").format("u") == "1" } }
def startDay = new java.text.SimpleDateFormat("yyyy-MM-dd").format(new Date()-7)
def stopDay = new java.text.SimpleDateFormat("yyyy-MM-dd").format(new Date()-1)
def dateOfTheDay = searchDay(startDay, stopDay);
def dateOfTheDayWithoutSquare = dateOfTheDay.join(", ")
return dateOfTheDayWithoutSquare

This will find the previous Monday starting from today
def cal = Calendar.instance
while (cal.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
cal.add(Calendar.DAY_OF_WEEK, -1)
}
Date lastMonday = cal.time
// print the date in yyyy-MM-dd format
println lastMonday.format("yyyy-MM-dd")
If you want to find the Monday previous to some other date replace the first line with:
def cal = Calendar.instance
Date someOtherDate = // get a date from somewhere
cal.time = someOtherDate

This should be a touch faster (no loop):
def cal = Calendar.instance
def diff = Calendar.MONDAY - cal.get(Calendar.DAY_OF_WEEK)
cal.add(Calendar.DAY_OF_WEEK, diff)
cal.time.format("yyyy-MM-dd")

Related

Check if between two dates is no longer working under iOS16.3

Using iOS16.3, XCode14.2, Swift5.7.2,
Why is the following method no longer working ?
I call this method by setting date = Date() and maximumDate = Date() as well...
According to this solution, it should work - but it doesn't
public class THManager : ObservableObject {
#Published public var minimumDate: Date = Date()
#Published public var maximumDate: Date = Date()
public func isBetweenMinAndMaxDates(date: Date) -> Bool {
print(min(minimumDate, maximumDate))
print(max(minimumDate, maximumDate))
print(min(minimumDate, maximumDate)...max(minimumDate, maximumDate))
print(date)
print((min(minimumDate, maximumDate)...max(minimumDate, maximumDate)).contains(date))
return (min(minimumDate, maximumDate)...max(minimumDate, maximumDate)).contains(date)
}
}
2022-02-08 19:45:51 +0000
2023-02-03 19:45:51 +0000
2022-02-08 19:45:51 +0000...2023-02-03 19:45:51 +0000
2023-02-03 19:45:51 +0000
false
It supposed to return true ! Why does it return false ???
By the way it works if date = Date() and maximumDate = Date().addingTimeInterval(1)
Very strange, isn't it ?
There is no need for such complexity. Date objects conform to the Comparable and Equatable protocols, so testing for a date being between 2 other dates is one line:
extension Date {
func between(start: Date, end: Date) -> Bool {
return self > start && self < end
}
}
You'd use that like this:
let date = Date()
if date.betweeen(start: someDate, end: someOtherDate) {
// the date is between the start and the end
} else {
// The date is not between the start and end dates
}
The above will only return true if the date in question is not equal to start or end date. You could easily change it to match dates that match the beginning and end dates by using >= and <= instead of > and < in the comparisons.
And as discussed in the comments, Date objects have sub-millisecond precision. Two dates that appear identical may be different by a tiny fraction of a second, the best way to verify your comparisons is to convert your Dates to decimal seconds and log the seconds values. (See the Date property timeIntervalSinceReferenceDate.)
Edit:
Check out this sample code using the above exension:
extension Date {
func between(start: Date, end: Date) -> Bool {
return self > start && self < end
}
var asStringWithDecimal: String {
return DateFormatter.localizedString(from: self, dateStyle: .medium, timeStyle: .medium) + " ( \(self.timeIntervalSinceReferenceDate) seconds)"
}
}
let now = Date()
for _ in (1...5) {
let random = Double.random(in: -1.5...1.5)
let test = now.advanced(by: random)
let start = now.advanced(by: -1)
let end = now.advanced(by: 1)
let isBetween = test.between(start: start, end: end)
let isOrNot = isBetween ? "is" : "is not"
let output = "\(test.asStringWithDecimal) \n \(isOrNot) between \n \(start.asStringWithDecimal) and \n \(end.asStringWithDecimal)"
print(output)
}
That will generate 5 random dates ± 1.5 seconds from the current date, and then test each one to see if it is within 1 second of the current date. It logs the result as both Date strings and Doubles, so you can see what's happening when the seconds match (but the fractions of a second likely don't match.)

How to get list of months between two dates in dart/flutter

I am trying to get a list of months between two dates in Dart
Example :
Input Date:
date 1 - 20/12/2011
date 2 - 22/08/2012
Now, my expected result should be :
12/2011
1/2012
2/2012
3/2012
4/2012
5/2012
6/2012
7/2012
8/2012
Thanks for your help!
You can do this:
var date1 = DateFormat("dd/MM/yyyy").parse("20/12/2021");
var date2 = DateFormat("dd/MM/yyyy").parse("22/08/2022");
while (date1.isBefore(date2)) {
print(DateFormat("M/yyyy").format(date1));
date1 = DateTime(date1.year, date1.month + 1);
}
You need
import 'package:intl/intl.dart';
Not exactly what OP has asked for, but I wanted to share this solution which takes me a while.
This solution also considers the day, and handle correctly the case for February 28.
static List<DateTime> extractMonthsInRange(DateTime from, DateTime to) {
//0. save day of from date
var daysInFromDate = from.day;
List<DateTime> monthsInRange = [DateTime(from.year, from.month)];
//1. get a list of months between 2 dates (without days)
while (from.isBefore(DateTime(to.year, to.month - 1))) {
var newFrom = DateTime(from.year, from.month + 1);
monthsInRange.add(newFrom);
from = newFrom;
}
//2. iterate months
return monthsInRange.map((month) {
var _lastDayOfMonth = lastDayOfMonth(month);
//2. if the day of the from date is < then the day of the last day of the month using the daysInFromDate
if (daysInFromDate < _lastDayOfMonth.day) {
return DateTime(month.year, month.month, daysInFromDate);
}
//3. else save the last day of the month (means that the month has less days)
return _lastDayOfMonth;
}).toList();
}
/// The last day of a given month
static DateTime lastDayOfMonth(DateTime month) {
var beginningNextMonth = (month.month < 12)
? DateTime(month.year, month.month + 1, 1)
: DateTime(month.year + 1, 1, 1);
return beginningNextMonth.subtract(Duration(days: 1));
}
Please feel free to improve my code in the comments.
you can use
date1.subtract(Duration(days: 7, hours: 3, minutes: 43, seconds: 56));
date1.add(Duration(days: 1, hours: 23)));
to add oder subtract days, months ...or what u like.... then do a if check in a loop or a while loop
something like this:
void main() {
DateTime a = DateTime.now();
DateTime b = a.add(Duration(days: 360));
DateTime c = a;
while (c.millisecondsSinceEpoch<b.millisecondsSinceEpoch)
{
c = c.add(Duration(days:31));
print('${c.month}/${c.year}');
}
}

DateTime fromMillisecondsSinceEpoch returning Incorrect Values

So, I'm working on a converter for changing JDE Julian Dates to Gregorian Dates and Vice Versa. I've run into a weird problem that I cannot find an answer for in my Julian to Gregorian code where non-leap years are calculating as leap years and leap years are calculating as non-leap years.
Exp: When I enter the JDE Julian Date '122095' it should return 04/05/2022 but instead returns 04/06/2022. When I changed the year to 2020, a leap year, it returned todays correct date of 04/05/2022 when it should have returned 04/04/2020.
I think the problem might be with my DateTime.fromMillisecondsSinceEpoch converter because it is return 2022-04-06 06:00:00.000Z and I don't know where the 6 in the hour spot is coming from or how to cancel it out. My Code is below.
Edit: I forgot, I used the code originally from THIS post.
Edit Edit: Okay that fixed the problem, I set "var millisecondsSinceEpoch = DateTime(convYear()).millisecondsSinceEpoch;" to "var millisecondsSinceEpoch = DateTime.utc(convYear()).millisecondsSinceEpoch;" and it was still giving me the wrong answer. I then thought to take the "isUtc: True" off of the end of "var dayOfYearDate = DateTime.fromMillisecondsSinceEpoch((millisecondsSinceEpoch + millisDayOfYear));" and that fixed the issue. The best I can figure is having the UTC bool at the end of that line was preventing millisecondsSinceEpoch from actually converting to UTC.
Thanks jamesdlin and James Heap for your help!
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
gregDate(var inputDate) {
var inputDate = '122095';
// Break down JDE date into individual pieces
var currentYear = int.parse(DateFormat('yy').format(DateTime.now()));
print('Current Year: $currentYear');
var splitYear = int.parse(inputDate.substring(1, 3));
print('Split Year: $splitYear');
var splitDay = int.parse(inputDate.substring(3, inputDate.length));
print('Split Day: $splitDay');
// Uses the current year to determine if our 2 digit date needs a 19 or 20 in the front
convYear() {
if (splitYear <= currentYear) {
var year = '20' + splitYear.toString();
return int.parse(year);
}
else {
var year = '19' + splitYear.toString();
return int.parse(year);
}
}
print('Converted Year: ${convYear()}');
// Takes 3 digit day in year and converts it to formatted date time.
convDate() {
var dayOfYear = splitDay;
var millisInADay = Duration(days: 1).inMilliseconds; // 86400000
print(millisInADay);
var millisDayOfYear = dayOfYear * millisInADay;
print(millisDayOfYear);
var millisecondsSinceEpoch = DateTime.utc(convYear()).millisecondsSinceEpoch;
print(millisecondsSinceEpoch);
var dayOfYearDate = DateTime.fromMillisecondsSinceEpoch((millisecondsSinceEpoch + millisDayOfYear), isUtc: true);
var result = DateFormat('MM/dd/${convYear()}').format(dayOfYearDate);
print(dayOfYearDate);
print(result);
return result;
}
return convDate();
}

Convert String to Date in Groovy

I want to get the date time add minutes or hours, below code is working for me
def now = new Date();
use(groovy.time.TimeCategory) {
def new_date = now + 10.minutes;
}
Now the issue is the "10.minutes" is a variable come from other place, once I got it, it change to string.
So is there any method i can convert String (10.minutes) to like a object which i can use it to add with a date?
This works for me:
def now = new Date()
use(groovy.time.TimeCategory) {
String t = "10.minutes"
def new_date = now + evaluate(t)
println new_date
}

scala dateTime weird results

I am getting unexpected results when I am running this code:
var DateFormat_in = new SimpleDateFormat("mm/dd/yyyy HH:mm:ss");
var DateFormat_out = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
var m ="4/29/2016 12:12:12"
println(str_timestamp(m,DateFormat_in,DateFormat_out)) // third
def str_timestamp(date_str:String,format_in:SimpleDateFormat,format_out: SimpleDateFormat): DateTime =
{
val date = format_in.parse(date_str)
val date_modified_str = format_out.format(date)
println(date_modified_str) // first
val temp = format_out.parse(date_modified_str);
println(temp) // second
val dateTime: DateTime = new DateTime(temp.getTime)
dateTime
}
I am getting the following:
2016-12-29 12:12:12
Fri Jan 29 12:12:12 CET 2016
2016-01-29T12:12:12.000+01:00
why the month is changing from one to one ? How to get it right ?
Please consult the javadoc of SimpleDateFormat. The correct pattern symbol for months is "M" (capital letter) and for minutes "m" (small).