how to get the first day of the first month of the current year in RPGLE - rpgle

dcl-s today date inz(*Sys) is the current sytem date
How do i get the first day of the first month of the current year in this format 2017/01/01

You may want to look into the %SUBST built-in function.
date = d'1999-02-17';
time = t'01.23.45';
timestamp = z'1999-02-17-01.23.45.98765';
num = %subdt(date:*YEARS);
// num = 1999
num = %subdt(time:*MN);
// num = 23

Here's a slick trick:
dcl-proc BuildDate;
dcl-pi *n date;
pyear int(5) const;
pmonth int(5) const;
pday int(5) const;
end-pi;
dcl-ds *n;
dateds date(*iso) inz(d'0001-01-01');
year zoned(4:0) pos(1);
month zoned(2:0) pos(6);
day zoned(2:0) pos(9);
end-ds;
year = pyear;
month = pmonth;
day = pday;
test(e) dateds;
if %error;
reset dateds;
endif;
return dateds;
end-proc;
Now all you need to do to construct a valid date given Day Month and Year is:
FirstDOY = BuildDate(%subdt(%date(): *Y): 1: 1);

Related

Node JS: calculating number working in each month between a two dates

I am trying to develop a code to generate number of working days in each month between two selected dates:
Eg: Start Date is 20-Oct-2022 and End Date is 14-Feb-2023.
I am able to generate net working days between two dates, however not for each month between the two dates.
I am expecting the code to provide output as:
Net working days in
Oct'22 is 8,
Nov'22 is 21,
Jan'23 is 22 and
Feb'22 is 10.
var startDate = new Date('20/10/2022');
var endDate = new Date('14/02/2023');
var numOfDates = getBusinessDatesCount(startDate,endDate);
function getBusinessDatesCount(startDate, endDate) {
let count = 0;
const curDate = new Date(startDate.getTime());
while (curDate <= endDate) {
const dayOfWeek = curDate.getDay();
if(dayOfWeek !== 0 && dayOfWeek !== 6) count++;
curDate.setDate(curDate.getDate() + 1);
}
return count;
}
like in above example you can calculate number of working days between two dates.

How to get the start and the end of date for each month with NaiveDate (Rust)?

How to get the last date of a month with chrono::NaiveDate. I try to search the manual but can't found anything useful.
use chrono::{NaiveDate, Datelike};
// from January to December m = 1 - 12
for m in 1..=12 {
let end = ..... ??
let start_date = NaiveDate::from_ymd(year, m, 1); /// each month starts with 1
let end_date = NaiveDate::from_ymd(year, m, end); /// here's the problem
container.push((start_date, end_date));
}
the closest would be to use Datelike::day https://docs.rs/chrono/0.4.6/chrono/trait.Datelike.html#tymethod.day0
and subtract 1 day from it, but I don't know how to do that with NaiveDate. I'm open to any suggestion. Thanks in advance.
Proposal for requested function
The function last_day_of_month already was proposed to be added to the chrono library on GitHub, but was not accepted.
The Code
The following solution works exactly like #Zeppi's solution, but uses a more rusty approach.
An Option<NativeDate> returned from NativeDate::from_ymd_opt is used to check whether the month is the 12. month to the switch to the edge-case, where the day is the last day of the month.
fn last_day_of_month(year: i32, month: u32) -> NaiveDate {
NaiveDate::from_ymd_opt(year, month + 1, 1)
.unwrap_or(NaiveDate::from_ymd(year + 1, 1, 1))
.pred()
}
Credits to #lifthrasiir on GitHub for the code
Sources
Chrono library Issue 69: Provide days_in_month()
Chrono library Issue 29: Leap year and last day of month
You can use pred()or pre_opt().
A very dirty solution that works like this
for m in 1..=12 {
let start_date = NaiveDate::from_ymd(2022, m, 1);
let mut end_date;
if m < 12 {
end_date = NaiveDate::from_ymd(2022, m + 1, 1).pred();
} else {
end_date = NaiveDate::from_ymd(2023, 1, 1).pred();
}
println!("{:?}", end_date);
}

How to get the last Friday of every Month for next 12 months using chrono?

How can I get the last Friday of each month for the next N months in Rust? I am able to get every Friday for the next N weeks but not able to find out how to determine if it is the last Friday of a month.
Currently I have:
use chrono::{Date, Datelike, DateTime, Duration, NaiveDate, NaiveDateTime, Utc, Weekday};
...
while index < 52 {
// Works to get friday at midnight
let new_date = NaiveDate::from_isoywd_opt(
now.iso_week().year(),
now.iso_week().week(),
Weekday::Fri
).unwrap();
let naive_datetime: NaiveDateTime = new_date.and_hms(0, 0, 0);
log::debug!("{:#?}", naive_datetime);
now = now + Duration::weeks(1);
index += 1;
}
But strangely I cannot find an easy way to determine the month cadence for this. I must be missing something obvious.
I was able to get it to work with the hint from #Jmb
with this code block.
while index < 52 {
let year = now.iso_week().year();
let month = now.month();
let week = now.iso_week().week();
// Works to get friday at midnight
let new_date = NaiveDate::from_isoywd_opt(
year,
week,
Weekday::Fri,
).unwrap();
let naive_datetime: NaiveDateTime = new_date.and_hms(0, 0, 0);
if naive_datetime.day() < 7 {
let previous_friday = naive_datetime - Duration::weeks(1);
let datetime: DateTime<Utc> = Utc.from_utc_datetime(&previous_friday);
dates.push(datetime);
}
now = now + Duration::weeks(1);
index += 1;
}
log::debug!("{:#?}", dates);

is there Groovy code to get today date and compare with another input date?

I want get the current date from the system(for eg- 2021-06-22) and compare with the input date (for eg- 2021-06-22) in groovy code.I tried the below code but im getting error in month field.
TimeZone tz = TimeZone.getTimeZone('UTC');
cal.setTimeZone(tz);
int hour = cal.get(Calendar.HOUR_OF_DAY) //Get the hour from timestamp
int min = cal.get(Calendar.MINUTE) //Get the Minutes from timestamp
int sec = cal.get(Calendar.SECOND)
int day = cal.get(Calendar.DAY_OF_WEEK)
int date = cal.get(Calendar.DATE)
int month= cal.get(Calendar.MONTH)
int year= cal.get(Calendar.YEAR)
​ println month

Groovy way to find dates in range by the day of the week

What would be the Groovy way to accomplish Joda Time example below:
LocalDate startDate = new LocalDate(2016, 11, 8);
LocalDate endDate = new LocalDate(2017, 5, 1);
LocalDate thisMonday = startDate.withDayOfWeek(DateTimeConstants.MONDAY);
if (startDate.isAfter(thisMonday)) {
startDate = thisMonday.plusWeeks(1); // start on next monday
} else {
startDate = thisMonday; // start on this monday
}
while (startDate.isBefore(endDate)) {
System.out.println(startDate);
startDate = startDate.plusWeeks(1);
}
And what about by more than 1 day of the week: MONDAY and TUESDAY, for example
Given your start and end date parameters, the following Groovy code (using Groovy Date.parse() and Date.format() mix-in functions, Groovy Date + int addition, Groovy String to int coercion, and a bit of algebra) seems to do the trick:
Date startDate = Date.parse("yyyy-MM-dd","2016-11-08")
Date endDate = Date.parse("yyyy-MM-dd","2017-05-01")
Date mondayStart = startDate + 6 - ((5 + (startDate.format("u") as int)) % 7)
while (mondayStart < endDate) {
println mondayStart
mondayStart += 7
}
Having said that, the while loop at the bottom is sort of... "open-ended". You can get a more analytical equivalent using Groovy's Range literal syntax and List.step() mix-in function. The following replaces only the while loop above:
(mondayStart..<endDate).step(7) { stepDate ->
println stepDate
}
Part 2: More than Monday
In order to work with other days of the week we need to replace the constant 5 in the mondayStart assignment with a suitable sub-expression based on the day of the week. Fortunately the following expression works quite nicely:
7 - Calendar."${weekDay.toUpperCase()}"
Putting the whole thing together and massaging a bit, it looks something like this:
def weekDaysInDateRange(Date startDate, Date endDate, String weekDay = "monday") {
startDate = startDate.clearTime()
endDate = endDate.clearTime()
def offset = 7 - Calendar."${weekDay.toUpperCase()}"
def startDOW = startDate.format("u") as int
def weekDayStartDate = startDate + 6 - (offset + startDOW) % 7
(weekDayStartDate..<endDate).step(7) { stepDate ->
println (stepDate.format("yyyy-MM-dd"))
}
}
With that function defined, the following test code:
def now = new Date()
def nextMonthIsh = new Date() + 30
println "$now --> $nextMonthIsh"
println "============================================================="
["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"]
.each { weekDay ->
println """
$weekDay
=========="""
weekDaysInDateRange(now, nextMonthIsh, weekDay)
}
Gives the following result:
Mon Sep 19 09:29:24 CDT 2016 --> Wed Oct 19 09:29:24 CDT 2016
=============================================================
sunday
==========
2016-09-25
2016-10-02
2016-10-09
2016-10-16
monday
==========
2016-09-19
2016-09-26
2016-10-03
2016-10-10
2016-10-17
tuesday
==========
2016-09-20
2016-09-27
2016-10-04
2016-10-11
2016-10-18
wednesday
==========
2016-09-21
2016-09-28
2016-10-05
2016-10-12
thursday
==========
2016-09-22
2016-09-29
2016-10-06
2016-10-13
friday
==========
2016-09-23
2016-09-30
2016-10-07
2016-10-14
saturday
==========
2016-09-24
2016-10-01
2016-10-08
2016-10-15

Resources