Java8 Date and Time with Instant API - datetime

I get dynamic date from my request,
Instant duration = request.getStartDate(); // my input is 2020-03-01T00:00:01Z
for (int i = 0; i < 12; i++) {
duration = duration.with(TemporalAdjusters.firstDayOfNextMonth ());
}
Basically i wanted to get first day of every month for 12 months, i tried with above code but getting exception,
java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: DayOfMonth
My output could be,
2020-04-01T00:00:01Z
2020-05-01T00:00:01Z
2020-06-01T00:00:01Z
:
:
2021-03-01T00:00:01Z
anything am missing here? tried with using plus()
duration.plus(30, ChronoUnit.DAYS);
I tried to convert instant to locateDate, then it prints fine, but for my required format i need to convert to Instant from localdate. I'm not seeing 1st day of next month.
2019-03-31T22:00:00Z
2019-04-30T22:00:00Z
2019-05-31T22:00:00Z
2019-06-30T22:00:00Z
2019-07-31T22:00:00Z
2019-08-31T22:00:00Z
2019-09-30T22:00:00Z
2019-10-31T23:00:00Z
2019-11-30T23:00:00Z
2019-12-31T23:00:00Z
any suggestion are appreciated. Thanks!

Much less fiddly than my namesake's answer: provided you convert to an OffsetDateTime up-front, there is no problem using the nice human-readable adjuster that you were trying to use initially.
OffsetDateTime duration = Instant.now().atOffset(ZoneOffset.UTC);
for (int i = 0; i < 12; i++) {
duration = duration.with(TemporalAdjusters.firstDayOfNextMonth());
}
The issue is that an Instant is an unambiguous point in time, irrespective of any specific timezone or geographic location. There is no specific date associated with an instant; what is Monday the 1st in one location may be Sunday the 31st in another, but it's still the same instant. That is why when trying to set a first day of the month, you get an exception.
If you convert to an OffsetDateTime, you are applying an offset (in this case UTC, so an offset of zero). This converts your data to a format in which a date is unambiguous.

Instant startInstant = request.getStartDate();
LocalDate start = startInstant.atZone(ZoneOffset.UTC).toLocalDate().withDayOfMonth(1);
for (int i = 0; i < 12; i++) {
System.out.println(start.plusMonths(i).atStartOfDay().toInstant(ZoneOffset.UTC));
}

Related

Wrong date difference calculated using momentjs

I am trying to calculate the number of days between two dates using moment js.
function (value) {
var expiration= moment(value).format('DDMMYYYY');
var today = moment().format('DDMMYYYY');
var dayToExpiration = moment(expiration- today).format('D[days] ,H[hours]');
console.log(today + " : " + expiration
console.log(dayToExpiration);
The result is:
11102018 : 28102020 //--> 11.10.2018 : 28.10.2018
1 days ,6 hours //why only one day??
Because your dayToExpiration variable should be a moment.Duration object, not a string.
The difference between two datetimes is a duration, not a datetime.
Short answer:
As John Madhavan-Reese stated in his answer, you have to use moment Duration to represent the diffecence between two moments in time.
Issue in the code sample:
In your code you are creating a moment object from the difference between expiration and today. This value is interpreded by moment as the number of milliseconds since the Unix Epoch (see moment(Number)), so you are creating a moment object for a random day around the 1st January 1970 (see the output of moment(expiration- today).format() ). The D token in format() stands for Day of Month, so it gives an "incorrect" output.
My suggested solution:
You can calculate difference using momentjs' diff() then you can create a duration using moment.duration(Number).
Finally you can get your desired output using moment-duration-format plug-in (by John Madhavan-Reese :D)
Here a live sample:
function getDiff(value) {
var expiration= moment(value); // Parse input as momement object
var today = moment(); // get now value (includes current time)
// Calculate diff, create a duration and format it
var dayToExpiration = moment.duration(Math.abs(today.diff(expiration))).format('D[days], H[hours]');
console.log(today.format('DDMMYYYY') + " : " + expiration.format('DDMMYYYY'));
console.log(dayToExpiration);
}
getDiff('2018-10-28');
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-duration-format/2.2.2/moment-duration-format.min.js"></script>
I am getting errors. this one works for me:
moment.duration(expiration.diff(today))._milliseconds / (1000*60*60*24));

MomentJS is reversing day and month in format()

I'm using momentJS to format some dates for a chartJS implementation.
In the chart i'm predicting the next 15 minutes worth of data so need to add the next 15 minutess worth of datetimes to my chartLabel variable.
I use the below function to achieve this. The issue is that the formatting for every other datetime seems to reverse the day and month. I have no idea why this is happening, has anyone seen this before?
predictMarketData(){
let lastDate = this.marketData[this.marketData.length-1][0]
lastDate = moment.unix(lastDate).add(1, 'minutes').format('DD/MM h:mm a')
for(var _i = 0; _i < 15; _i++){
this.chartLabels.push(lastDate);
lastDate = moment(lastDate).add(1, 'minutes').format('DD/MM h:mm a');
}
}
It appears to add minutes correctly but the day month formatting appears to reverse every other, screenshot provided.
Any help would be much appreciated!

Qt three ComboBoxes for a date

I have been looking around Google and Stackoverflow, but I have yet to find out if there is any simple solution to auto-filling three comboboxes to represent a correct date (like YYYY-MM-DD). I would presume it would be related to QCalendarWidget. Any ideas?
I want to be able to scroll through current time to dates from X years ago, it shouldn't have non-existant dates like February 29, 2011. Not sure if this is asking for too much.
Now i get what's your idea.
The answer is simple. Make three combo boxes: Day (1 - 31), Month (1 - 12) and Year (i.e. 1999 - 2012). Create "OK" button. No ultra-logic is needed.
After button being pressed just validate the date by creating QDate object with three numbers given by user and calling QDate::isValid(). If it isn't, create some warning prompt and ask user to change something in input.
The best way to validate the data entered by user is to override QDialog::done() method.
void Dialog::done(int r)
{
if(r == QDialog::Accepted) {
QDate date;
//Create QDate from comboboxes' values
...
if(!date.isValid()) {
//Some warning to user.
return;
}
}
QDialog::done(r);
}
int X = 2;
QDate date = QDate::currentDate(), lastDate = date.addYears(-X);
for(; date > lastDate; date = date.addDays(-1))
ui->comboBox->addItem(date.toString("yyyy-MM-dd"));

Is there a better way to encode a (MS) DateTime as an Int?

BACKGROUND (ok to ignore/skip):
I feel like there should be a better way to do what I'm doing, but I don't know what it is and I think my solution works, but I thought I'd ask in case there is something more elegant or faster or whatever.
I am developing a web page with MS Razor MVC which uses Html.DropDownList, which gives a pick list UI control which maps choices as display strings to integer ID codes. (I don't think I can have it map strings to DateTime values.)
But in a couple of cases, I want to choose from dates that are stored as DateTime objects. I realize I could make yet another table in memory that relates ID codes to DateTime values, but I thought instead (and also because I think I may want to encode dates as ints for yet another workaround of web page annoyances), I would encode the date as an int.
PROBLEM:
How best to convert the date of a DateTime object as an int value, and then later set a DateTime's date back to that date from the encoded int. The main ugliness of my solution is that DateTime provides a read-only DayOfYear function, but no way I know of to set a date back to (Date, DayOfYear), so I wrote a method with a loop, which is cute but probably slowish.
MY CURRENT (OK) SOLUTION:
public int encodeDate(DateTime date)
{
return ((date.Year - 2012) * 400) + date.DayOfYear;
}
public DateTime decodeDateCode(int dateCode)
{
int year = (dateCode / 400) + 2012;
int day = dateCode % 400;
// MS DateTime doesn't provide a direct reverse conversion for DayOfYear, so find it:
int month = 1;
int mThresh = DateTime.DaysInMonth(year, month);
while (day > mThresh)
{
day -= mThresh;
month++;
mThresh = DateTime.DaysInMonth(year, month);
}
DateTime dateValue = new DateTime(year, month, day);
return dateValue;
}
Ho about to format the timestamp as POSIX time (POSIX time / Unix time, see http://en.wikipedia.org/wiki/Unix_time)?
I had a similar problem myself and found a great solution here: Convert a Unix timestamp to a .NET DateTime
From the link:
DateTime ConvertFromUnixTimestamp(double timestamp)
{
}
double ConvertToUnixTimestamp(DateTime date)
{
}

Total Time reports with XtraScheduler control

Is any easy way to make "total time" reports with XtraScheduler control.
I need couple reports that will calculate total time by day/week/month for each resorce and appointment type.
Is posible to do this with XtraSchedulerReport or I must calculate this manualy?
There aren't any built in functions to calculate the total time by resource and appointment type, but it's definitely possible to do this using XtraScheduler. Check out the two following examples for better details on how:
http://www.devexpress.com/Support/Center/e/E977.aspx
http://www.devexpress.com/Support/Center/e/E121.aspx
:)
Also, try something like this:
internal static TimeIntervalCollectionEx CalculateBusyTime(AppointmentBaseCollection appointments, TimeInterval interval) {
TimeIntervalCollectionEx busyIntervals = new TimeIntervalCollectionEx();
int count = appointments.Count;
for (int i = 0; i < count; i++)
busyIntervals.Add(TimeInterval.Intersect(interval, appointments[i].CreateInterval()));
return busyIntervals;
}

Resources