I've been looking for a way to accurately calculate the next/future billing date in a way that a month will not be skipped. For example for Jun 31 I want the next billing date to be Feb 28 (or 29 when applicable).
I found this great solution.
Here is an update of that code to support more than 1 month in the future.
Hope that helps.
Code:
function calculateBillingDate($startDate, $numberOfCycles = 1) {
$currentMonth = date('n', $startDate);
$nextMonth = (($currentMonth + $numberOfCycles) % 12);
if ($nextMonth === 0) {
$nextMonth = 12;
}
$targetDate = new \DateTime();
$targetDate->setTimestamp($startDate);
$targetDate->add(new \DateInterval('P' . $numberOfCycles . 'M'));
while ((int)$targetDate->format('m') !== $nextMonth) {
$targetDate->sub(new \DateInterval('P1D'));
}
return $targetDate;
}
Related
I need help with some quick coding with google apps script, linking to my googlesheets spreadsheet.
In the googlespreadsheets, I have a cell with the value “26-Jun-2020”. It is a date.
I want to use google apps script to calculate the number of days difference between that date (“26-Jun-2020”) and today’s day, but it won’t do the calculation for me somehow.
If I print only “expiry_date[i]” using Logger.log(expiry_date[i]), it will provide the output “Fri Dec 17 2021 01:00:00 GMT-0500 (Eastern Standard Time) “
function Put_Options_Expiry_Alert() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Long equity (sell puts)");
//var timeZone = AdsApp.currentAccount().getTimeZone(); //Get timezone of current spreadsheet
var status = sheet.getRange("F:F").getValues();
var expiry_date = sheet.getRange("M:M").getValues();
var potential_capitaloutlay_USD = sheet.getRange("Z:Z").getValues();
Logger.log("Length of status = " + status.length);
Logger.log("Length of expiry_date = " + expiry_date.length);
Logger.log("Length of potential_capitaloutlay_USD = " + potential_capitaloutlay_USD.length);
for (var i = 0; i < status.length; i++) {
if (status[i] == "Entered") { //Evaluate if this is a live Put position
//Calculate the time difference of two dates using date2. getTime() – date1. getTime();
//Calculate the no. of days between two dates, divide the time difference of both the dates by no. of milliseconds in a day (1000*60*60*24)
Logger.log("expiry date is = "+expiry_date[i]);
Logger.log("today's date is = "+Date());
var days_to_expiry = dateDiffInDays(expiry_date[i],Date());
Logger.log(days_to_expiry);
}
}
}
// Function that returns the number of days difference between DateA and DateB
// DateA and DateB are javascript Date objects
function dateDiffInDays(DateA, DateB) {
var milliseconds_per_day = 1000 * 24 * 60; // number of milliseconds in a day
const utcA = Date.UTC(2021, DateA.getMonth(), DateA.getDate());
const utcB = Date.UTC(2020, DateB.getMonth(), DateB.getDate());
return Math.floor((utc2 - utc1) / milliseconds_per_day);
}
function timeDiffDays(Start, End) {
var day = 86400000;
var t1 = new Date(Start).valueOf();
var t2 = new Date(End).valueOf();
var d = t2 - t1;
return Math.floor(d / day);
}
I have a date returned by a json, it is in the following variable as string:
val dateEvent = "2019-12-28 21:00:00"
The calculation I need is to know how many days hours minutes are left with the current date.
I have found some solutions but these use as input "2019-12-28" and I have my format with the time included.
java.time
Since Java 9 you can do (sorry that I can write only Java code):
DateTimeFormatter jsonFormatter = DateTimeFormatter.ofPattern("u-M-d H:mm:ss");
String dateEvent = "2019-12-28 21:00:00";
Instant eventTime = LocalDateTime.parse(dateEvent, jsonFormatter)
.atOffset(ZoneOffset.UTC)
.toInstant();
Duration timeLeft = Duration.between(Instant.now(), eventTime);
System.out.format("%d days %d hours %d minutes%n",
timeLeft.toDays(), timeLeft.toHoursPart(), timeLeft.toMinutesPart());
When I ran the code just now, the output was:
145 days 4 hours 19 minutes
In Java 6, 7 and 8 the formatting of the duration is a bit more wordy, search for how.
Avoid SimpleDateFormat and friends
The SimpleDateFormat and Date classes used in the other answer are poorly designed and long outdated. In my most honest opinion no one should use them in 2019. java.time, the modern Java date and time API, is so much nicer to work with.
Use the following function:
fun counterTime(eventtime: String): String {
var day = 0
var hh = 0
var mm = 0
try {
val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
val eventDate = dateFormat.parse(eventtime)
val cDate = Date()
val timeDiff = eventDate.time - cDate.time
day = TimeUnit.MILLISECONDS.toDays(timeDiff).toInt()
hh = (TimeUnit.MILLISECONDS.toHours(timeDiff) - TimeUnit.DAYS.toHours(day.toLong())).toInt()
mm =
(TimeUnit.MILLISECONDS.toMinutes(timeDiff) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(timeDiff))).toInt()
} catch (e: ParseException) {
e.printStackTrace()
}
return if (day == 0) {
"$hh hour $mm min"
} else if (hh == 0) {
"$mm min"
} else {
"$day days $hh hour $mm min"
}
}
counterTime(2019-08-27 20:00:00)
This returns 24 days 6 hour 57 min
Note: The event date should always be a future date to the current date.
in flutter we can get current month using this
var now = new DateTime.now();
var formatter = new DateFormat('MM');
String month = formatter.format(now);
But how to get the last month date? Especially if current date is January (01). we can't get the right month when we use operand minus (-) , like month - 1.
You can just use
var prevMonth = new DateTime(date.year, date.month - 1, date.day);
with
var date = new DateTime(2018, 1, 13);
you get
2017-12-13
It's usually a good idea to convert to UTC and then back to local date/time before doing date calculations to avoid issues with daylight saving and time zones.
We can calculate both first day of the month and the last day of the month:
DateTime firstDayCurrentMonth = DateTime.utc(DateTime.now().year, DateTime.now().month, 1);
DateTime lastDayCurrentMonth = DateTime.utc(DateTime.now().year, DateTime.now().month + 1).subtract(Duration(days: 1));
DateTime.utc takes in integer values as parameters: int year, int month, int day and so on.
Try this package, Jiffy, it used momentjs syntax. See below
Jiffy().subtract(months: 1);
Where Jiffy() returns date now. You can also do the following, the same result
var now = DateTime.now();
Jiffy(now).subtract(months: 1);
We can use the subtract method to get past month date.
DateTime pastMonth = DateTime.now().subtract(Duration(days: 30));
Dates are pretty hard to calculate. There is an open proposal to add support for adding years and months here https://github.com/dart-lang/sdk/issues/27245.
There is a semantic problem with adding months and years in that "a
month" and "a year" isn't a specific amount of time. Years vary by one
day, months by up to three days. Adding "one month" to the 30th of
January is ambiguous. We can do it, we just have to pick some
arbitrary day between the 27th of February and the 2nd of March.
That's why we haven't added month and year to Duration - they do not
describe durations.
You can use the below code to add months in a arbitrary fashion (I presume its not completely accurate. Taken from the issue)
const _daysInMonth = const [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
bool isLeapYear(int value) =>
value % 400 == 0 || (value % 4 == 0 && value % 100 != 0);
int daysInMonth(int year, int month) {
var result = _daysInMonth[month];
if (month == 2 && isLeapYear(year)) result++;
return result;
}
DateTime addMonths(DateTime dt, int value) {
var r = value % 12;
var q = (value - r) ~/ 12;
var newYear = dt.year + q;
var newMonth = dt.month + r;
if (newMonth > 12) {
newYear++;
newMonth -= 12;
}
var newDay = min(dt.day, daysInMonth(newYear, newMonth));
if (dt.isUtc) {
return new DateTime.utc(
newYear,
newMonth,
newDay,
dt.hour,
dt.minute,
dt.second,
dt.millisecond,
dt.microsecond);
} else {
return new DateTime(
newYear,
newMonth,
newDay,
dt.hour,
dt.minute,
dt.second,
dt.millisecond,
dt.microsecond);
}
}
To get a set starting point at the start of a month, you can use DateTime along with the Jiffy package.
DateTime firstOfPreviousMonth
= DateTime.parse(
Jiffy().startOf(Units.MONTH)
.subtract(months: 1)
.format('yyyy-MM-dd'). //--> Jan 1 '2021-01-01 00:00:00.000'
);
var fifthOfMonth
= firstOfPreviousMonth.add(Duration(days: 4)); //--> Jan 5 '2021-01-05 00:00:00.000'
or
DateTime endOfPreviousMonth
= DateTime.parse(
Jiffy().endOf(Units.MONTH)
.subtract(months: 2)
.format('yyyy-MM-dd'). //--> Dec 30 '2020-12-31 00:00:00.000'
// endOf always goes to 30th
);
var previousMonth
= endOfPreviousMonth.add(Duration(days: 2)); //--> Jan 1 '2021-01-01 00:00:00.000'
DateFormat('MMMM yyyy')
.format(DateTime(DateTime.now().year, DateTime.now().month - 2)),
List<DateTime> newList = [];
DateFormat format = DateFormat("yyyy-MM-dd");
for (var i = 0; i < recents.length; i++) {
newList.add(format.parse(recents[i]['date'].toString()));
}
newList.sort(((a, b) => a.compareTo(b)));
var total = 0;
for (var i = 0; i < newList.length; i++) {
if (DateTime.now().difference(newList[i]).inDays < 30) {
print(newList[i]);
total++;
}
}
print(total);
You can use this to fetch the last 30 days.
In addition to Günter Zöchbauer Answer
var now = new DateTime.now();
String g = ('${now.year}/ ${now.month}/ ${now.day}');
print(g);
I would like to subtract days from the current date in TypeScript.
For example, if the current date is October 1st, 2017, I would like to subtract 1 day to get September 30th, 2017, or if I want to subtract 3 days I would get September 28th etc.
This is what I have so far, the result is I received December 31st, 1969. Which I assume means that tempDate.getDate() is returning zero, as in the Epoch of January 1, 1970.
This is my code, the goal is to return the previous working day.
protected generateLastWorkingDay(): Date {
var tempDate = new Date(Date.now());
var day = tempDate.getDay();
//** if Monday, return Friday
if (day == 1) {
tempDate = new Date(tempDate.getDate() - 3);
} else if (1 < day && day <= 6) {
tempDate = new Date(tempDate.getDate() - 1);
}
return tempDate;
}
getDate returns the date of the month (1-31), so creating a new Date from it treats that number as "milliseconds since epoch".
What you probably want is to use setDate to change the date as it automatically handled going backwards through months/years.
protected generateLastWorkingDay(): Date {
const lastWorkingDay = new Date();
while(!this.isWorkingDay(lastWorkingDay)) {
lastWorkingDay.setDate(lastWorkingDay.getDate()-1);
}
return lastWorkingDay;
}
private isWorkingDay(date: Date) {
const day = date.getDay();
const isWeekday = (day > 0 && day < 6);
return isWeekday; // && !isPublicHoliday?
}
This is how I did
let yesterday=new Date(new Date().getTime() - (1 * 24 * 60 * 60 * 1000));
let last3days=new Date(new Date().getTime() - (3 * 24 * 60 * 60 * 1000));
We need to minus (no_of_days) * 24 * 60 * 60 * 1000 from current date.
You can just
const current = new Date()
and then
const numberOfDaysToSubstract= 3;
const prior = new Date().setDate(current.getDate) - numberOfDaysToSubstract);
you can see an example of this here
https://codepen.io/Jeysoon/pen/poNZRwd?editors=1112
I want to make a js function. When I input year and month number, if there is a black friday in that month, it will returns true.
Is there any simlar moment.js method or function to do this? Thx.
You can create a moment object representing the 13th of the given month using using moment({unit: value, ...}); then you can get day of week using day(). As docs says:
This method can be used to set the day of the week, with Sunday as 0 and Saturday as 6.
so you can check if day() is equal to 5 (Friday).
Here a working example:
function hasBlackFriday(year, month) {
return (moment({y: year, M: month, d: 13}).day() === 5);
}
// Test foreach month of 2017
for(var i=0; i<12; i++){
console.log(hasBlackFriday(2017, i));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
Keep in mind that, as moment({unit: value, ...}); docs says:
Note that like moment(Array) and new Date(year, month, date), months are 0 indexed.
As Matt Johnson highlighted in the comments, you can get the same result also using native JavaScript Date object, here a sample:
function hasBlackFriday(year, month) {
return (new Date(year, month, 13).getDay() === 5);
}
// Test foreach month of 2017
for(var i=0; i<12; i++){
console.log(hasBlackFriday(2017, i));
}
This function returns the date for last Friday of the given month m and year y.
function hasBlackFriday(y, m) {
var date = moment(new Date(y, m - 1, '1'))
result = date.endOf('month');
while (result.day() !== 5) {
result.subtract(1, 'day');
}
return result;
}
console.log(hasBlackFriday(2017, 4).format('M DD YY'))