I have a requirement, in which, I can provide startDate (27JUL14) and endDate (30JUN15), and dayOfWeek(4,5,6)
Day of week represent -
1 - Monday
2 - Tuesday
3 - Wednesday
4 - Thursday
5 - Friday
6 - Saturday
7 - Sunday
The duration between startDate and endDate is 6 months long, I need to get all the specific dates that match the provided dayOfWeek for the interval of time between StartDate and EndDate.
public void calculateScheduleDates(Date periodOfOperationFrom, Date periodOfOperationTo, String dow)
{
String[] weekDays = dow.replaceAll("\\[", "").replaceAll("\\]", "").split(",");
int[] dayOfWeek = new int[weekDays.length];
for (int i = 0; i < weekDays.length; i++)
{
try
{
dayOfWeek[i] = Integer.parseInt(weekDays[i]);
dateTime = (DateTime) DateTime.now().withDayOfWeek(dayOfWeek[i]);
System.out.println("DateTime :\t"+dateTime);
}
catch (NumberFormatException nfe) {};
}
}
I have tried to get weeks (Starting date of week)
public void getWeekDate(String beginDate, String finishDate)
{
System.out.println("Begindate "+ beginDate + "\t EndDate \t"+finishDate);
LocalDate startDate = new LocalDate(2014, 12, 1);
LocalDate endDate = new LocalDate(2015, 6, 30);
/* These are date format for startDate and endDate which are not working with 27JUL14 format.
This also needs to be changed
*/
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))
{
dates.add(startDate);
startDate = startDate.plusWeeks(1);
}
System.out.println("Size of List Of Date :\t"+dates+"\n"+dates.size());
}
Now I have tried to crate scheduleDates:
public void calculateFlightLegScheduleDates(LocalDate[] periodOfOperationFrom, String dow)
{
/*
* Process as per the Weeks received from dates list and set it to current week and process
* alongwith dow and for each date, loop in to set the schedule Record.
* */
// the incoming weeks "periodOfOperationFrom" in list format, and I need to set the week starting date to the weeks start dates even in future and find the week dates from the dow parameter. This is the point where I am facing challenge.
}
I need this solution in Java.
I have tried to use jodatime library, but couldn't get any specific result.
Note: Please note that, I need the specific dates between mentioned duration not just number of days.
Please help, I need this very much.
One possibility:
parse startDate/endDate
find the first date from startDate marching the wanted dayOfWeek
print that date then add 7 days and repeat until endDate is reached.
Sample code:
public class App {
public static void main(final String[] args) {
calculateScheduleDates("27JUL14", "30JUN15", DateTimeConstants.MONDAY);
}
private static void calculateScheduleDates(final String startDate, final String endDate, final int dayOfWeek) {
final DateTimeFormatter formatter = DateTimeFormat.forPattern("ddMMMy").withLocale(Locale.US);
final LocalDate end = LocalDate.parse(endDate, formatter);
LocalDate start = LocalDate.parse(startDate, formatter);
// find the first matching date
while (start.getDayOfWeek() != dayOfWeek) {
start = start.plusDays(1);
}
// compute and print results
while (start.compareTo(end) < 0) {
System.out.println(start.toString(formatter).toUpperCase());
start = start.plusDays(7);
}
}
}
Output:
28JUL14
04AUG14
...
15DEC14
22DEC14
...
22JUN15
29JUN15
Related
This question already has answers here:
SimpleDateFormat ignoring month when parsing
(4 answers)
Closed 1 year ago.
I want to add 2 Months in another Date but he only add 60 Days in Date and there is no increment in Months of the Date as well as in Year.
I'm using following code for adding Date in another Date. Days adding correctly but there is no increment in Month of Date. if I add 60 Days then he add but again there is no increment in Month as well as in Year. If someone help me to resolve problem then I really thank full!!!
String dob = "06/05/2021";
SimpleDateFormat sdf = new SimpleDateFormat("dd/mm/yyyy");
Calendar c = Calendar.getInstance();
try {
c.setTime(sdf.parse(dob));
} catch (ParseException e) {
e.printStackTrace();
}
c.add(Calendar.DATE, 60);
c.add(Calendar.MONTH,2); // Not Working
sdf = new SimpleDateFormat("dd/mm/yyyy");
Date resultdate = new Date(c.getTimeInMillis());
String incToDate = sdf.format(resultdate);
Toast.makeText(this, incToDate, Toast.LENGTH_SHORT).show();
Your pattern is not correct, it basically reads two digits for day of month/two digits for minute of hour/4 digits for year. I'm guessing you did not want any minutes of hour in this pattern, so change the lower-case ones to upper-case ones.
If you can use java.time, you could get the desired result like this:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
// provide an example date as String
String dob = "06/05/2021";
// create a formatter that can parse a String in the given format
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd/MM/uuuu");
// parse the String to a LocalDate using the previously defined formatter
LocalDate localDob = LocalDate.parse(dob, dtf);
// print the (formatted) result just to see if parsing has worked
System.out.println("Just parsed " + localDob.format(dtf));
// add two months and print a result phrase
LocalDate localDobTwoMonthsLater = localDob.plusMonths(2);
System.out.println("Adding two months results in "
+ localDobTwoMonthsLater.format(dtf));
// for completeness, add 60 days and print the result
LocalDate localDobSixtyDaysLater = localDob.plusDays(60);
System.out.println("Adding sixty days results in "
+ localDobSixtyDaysLater.format(dtf));
}
}
This code prints
Just parsed 06/05/2021
Adding two months results in 06/07/2021
Adding sixty days results in 05/07/2021
Apparently in a simple problem but I am being complicated with the treatment of dates. I need a date comparator that receives as parameters a date in yyyy-MM-dd format and a number (age) and that determines if it is above that number or below.
For example for 18, 1999-01-01 is above and would return true, but for 2010-01-01 false. If it were the year 2001, it would compare with the current month and year, that is, 2001-06-18 that was greater or less
I have this code using the gregorian api for the current date but I am unable.
I have this done
public static void main (String args[]) throws ParseException{
//SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
//Date fechaInicial=(Date) dateFormat.parse("1999-01-01");
java.sql.Datedate1 = new Date(1999-01-01);
Calendar date2 = Calendar.getInstance();
boolean res = date(date1, date2);
}
public static boolean date(java.sql.Datedate1, Calendar date2 ){
//int year=18;
int y= date2.get(Calendar.YEAR)-18;
int m = date2.get(Calendar.MONTH)+1;
int d = date2.get(Calendar.DAY_OF_MONTH);
System.out.println(
String fechacompleta= y+"-"+m+"-"+d;
System.out.println(fechacompleta);
return ;
}
You can write your date method using java.time.LocalDate like this:
public static boolean date(LocalDate ld, int age) {
Period p = Period.between(ld, LocalDate.now());
return p.getYears() >= age;
}
It computes the Period between a certain date and now, and returns whether that period is greater than or equal to 18 years.
You can create a LocalDate like this:
LocalDate ld = LocalDate.parse("2001-12-23", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
And pass it into date:
if (date(ld, 18)) {
// 18 or above!
}
My Java FX app handles hours worked. I have work start and end time in 2 date fields. I succeeded in calculating the differences between 2 datesTime; but now how could I check if the result is in a night or day range???? The day begin at 6 and ends at 22h. For example someone who worked between 3Am till 11Pm.
Here is below how I did to have the total number of hours worked.
public void CalculNbreJourTravaille() {
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyy HH:mm");
try {
Date ddtt = format.parse(ddt.getText());
Date dftt = format.parse(dft.getText());
long diff = dftt.getTime() - ddtt.getTime();
long diffhours = diff / (60*60*1000)%24;
long diffdays = diff/(24*60*60*1000);
long total = diffhours + (diffdays*24);
result.setText(total + " Hours");
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
We have workers who can work beyond 10PM, and the pay would not be the same. If they work after 10pm, they will have a special pay. We pay at the end of the work. They could would work only 10 days or more.
You should use the new DateTimeFormatter class to give you a LocalDateTime object, which you can pull the hour from.
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
LocalDateTime localDateTimeFrom = format.parse(dateFrom.getText(), LocalDateTime::from);
LocalDateTime localDateTimeTo = format.parse(dateTo.getText(), LocalDateTime::from);
int hoursFrom = localDateTimeFrom.getHour();
int hoursTo = localDateTimeTo.getHour();
boolean workedNight = hoursFrom < 6 || hoursTo > 22;
Here’s my attempt to cover all of your requirements. I wrote the code before reading that you don’t require that summer time (DST) is taken into account, so I am using ZonedDateTime to get correct hours also across summer time transitions. For the same reason I need to iterate over each day. For each date I calculate the hours worked at night time and the hours worked at day time.
If you want to make sure that summer time is not taken into account, use LocalDateTime instead of ZonedDateTime. In this case there may also be a possible performance gain in calculating the whole work days in one lump rather than one day at a time.
The code below uses 28/03/2018 03:00 and 29/03/2018 23:30 as example start and end time. Expected total hours worked are 44.5 since one day is 24 hours and there are 20.5 hours from 03:00 to 23:30. The expected day time hours are 32 since there are 16 daytime hours each of the two days. This leaves 12.5 hours as night time. And indeed the code prints
Day 32.0 hours; night 12.5 hours
The program follows. Please fill in the correct time zone where I put America/Monterey.
static ZoneId zone = ZoneId.of("America/Monterrey");
static LocalTime dayStart = LocalTime.of(6, 0);
static LocalTime dayEnd = LocalTime.of(22, 0);
static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d/M/uuuu H:mm");
public static void main(String[] args) {
String workStartString = "28/03/2018 03:00";
String workEndString = "29/03/2018 23:30";
calculateWorkingHours(workStartString, workEndString);
}
public static void calculateWorkingHours(String workStartString, String workEndString) {
ZonedDateTime workStart
= LocalDateTime.parse(workStartString, formatter).atZone(zone);
ZonedDateTime workEnd
= LocalDateTime.parse(workEndString, formatter).atZone(zone);
if (workEnd.isBefore(workStart)) {
throw new IllegalArgumentException("Work end must not be before work start");
}
LocalDate workStartDate = workStart.toLocalDate();
LocalDate workEndDate = workEnd.toLocalDate();
Duration workedDaytime = Duration.ZERO;
// first calculate work at nighttime before the start date, that is, work before 06:00
Duration workedNighttime
= calculateNightTime(workStartDate.minusDays(1), workStart, workEnd);
for (LocalDate d = workStartDate; ! d.isAfter(workEndDate); d = d.plusDays(1)) {
workedDaytime = workedDaytime.plus(calculateDayTime(d, workStart, workEnd));
workedNighttime = workedNighttime.plus(calculateNightTime(d, workStart, workEnd));
}
double dayHours = workedDaytime.toMinutes() / (double) TimeUnit.HOURS.toMinutes(1);
double nightHours = workedNighttime.toMinutes() / (double) TimeUnit.HOURS.toMinutes(1);
System.out.println("Day " + dayHours + " hours; night " + nightHours + " hours");
}
/**
* Calculates amount of work in daytime on d,
* that is between 06:00 and 22:00 on d.
* Only time that falls with in workStart to workAnd
* and also falls within 06:00 to 22:00 on d is included.
*
* #param d The date for which to calculate day work
* #param workStart
* #param workEnd
* #return Amount of daytime work on the said day
*/
private static Duration calculateDayTime(LocalDate d, ZonedDateTime workStart, ZonedDateTime workEnd) {
ZonedDateTime dayStartToday = d.atTime(dayStart).atZone(zone);
ZonedDateTime dayEndToday = d.atTime(dayEnd).atZone(zone);
if (workStart.isAfter(dayEndToday) || workEnd.isBefore(dayStartToday)) {
return Duration.ZERO;
}
// restrict calculation to daytime on d
if (workStart.isBefore(dayStartToday)) {
workStart = dayStartToday;
}
if (workEnd.isAfter(dayEndToday)) {
workEnd = dayEndToday;
}
return Duration.between(workStart, workEnd);
}
/**
* Calculates amount of night work in the night after d,
* that is from 22:00 on d until 06:00 the next morning.
*
* #param d The date for which to calculate night work
* #param workStart
* #param workEnd
* #return Amount of nighttime work in said night
*/
private static Duration calculateNightTime(LocalDate d, ZonedDateTime workStart, ZonedDateTime workEnd) {
assert ! workEnd.isBefore(workStart);
ZonedDateTime nightStart = d.atTime(dayEnd).atZone(zone);
ZonedDateTime nightEnd = d.plusDays(1).atTime(dayStart).atZone(zone);
if (workEnd.isBefore(nightStart) || workStart.isAfter(nightEnd)) {
return Duration.ZERO;
}
// restrict calculation to the night after d
if (workStart.isBefore(nightStart)) {
workStart = nightStart;
}
if (workEnd.isAfter(nightEnd)) {
workEnd = nightEnd;
}
return Duration.between(workStart, workEnd);
}
You can check the LocalTime part of a LocalDateTime to have a simple check using isAfter and isBefore.
I will use those values for this example.
LocalDateTime start = LocalDateTime.of(2018, Month.APRIL, 30, 23, 0);
LocalDateTime end = LocalDateTime.of(2018, Month.MAY, 1, 5, 0);
Then define the limit for the night.
LocalTime startNight = LocalTime.of(22, 0);
LocalTime endNight = LocalTime.of(6, 0);
And simply use get the LocalTime of both date and check if they are in the range. You can get the value using toLocalTime.
if(start.toLocalTime().isAfter(startNight) &&
end.toLocalTime().isBefore(endNight)){
System.out.println("NIGHT TIME");
} else {
System.out.println("DAY TIME");
}
NIGHT TIME
The output is valid since we start at 23:00 and end at 05:00.
Using this allow a simpler solution if you need to define a time like LocalTime.of(5,45) for 5:45
This is an example, this might need some adaptation if it is allowed to start part 22 but keep working after 6. This is just an example on how to use those methods.
This is easier, if you use the java.time API. You simply need to check, if the dates differ or if the starting time not in the range from 6:00 to 22:00:
private static final LocalTime START_TIME = LocalTime.of(6, 0); // 06:00
private static final LocalTime END_TIME = LocalTime.of(22, 0); // 22:00
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
// parse from input strings
LocalDateTime start = LocalDateTime.parse(startText, FORMATTER);
LocalDateTime end = LocalDateTime.parse(endText, FORMATTER);
boolean nightTime =
!start.toLocalDate().equals(end.toLocalDate())
|| start.toLocalTime().isBefore(START_TIME)
|| end.toLocalTime().isAfter(END_TIME);
// todo: change output to gui
System.out.println("night time: " + nightTime);
System.out.println("duration : " + Duration.between(start, end).toHours());
Define two formatters. One Fromatter to get date with time from edittext. And other On to get 12AM of that day. Now we need Date Objects corresponding to 6AM and 11PM of the same day. We can get those by adding that much milliseconds to the 12AM Object. These added dates can be used for comparison.
SimpleDateFormat df_zero_hours = new SimpleDateFormat("dd/MM/yyy");
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm");
Date ddtt = format.parse(ddt.getText()); //Work Start Time
Date dftt = format.parse(dft.getText()); //Work End Time
Date dateStart = df_zero_hours.parse(ddt.getText()); //12AM of the day job started
Date dayStart = new Date();
dayStart.setTime(dateStart.getTime()+6*60*60*1000); // Get 6AM of that day
Date dayEnd = new Date();
dayEnd.setTime(dateStart.getTime()+22*60*60*1000); //Get 10PM of that day
// Now check the worked hours. in Whatever way you need
boolean isBefore6AM = (dayStart.getTime()-ddtt.getTime())>0;
boolean isAfter10PM = (dftt.getTime()-dayEnd.getTime())>0;
This question already has answers here:
Does Java support Julian calendar?
(4 answers)
Closed 5 years ago.
I need to create a program that reads dates from a .csv file and convert it so that 13 days are added. I already did that but somehow it does not add the following dates as wished. It also goes over 30 days, which is not supposed to happen for example 2001-12-42.
public static void main(String[] args) throws FileNotFoundException, ParseException {
File fread = new File("src/daten-greg.csv");
File fwrite = new File("src/daten-jul.csv");
Scanner s = new Scanner(fread);
PrintStream print = new PrintStream(fwrite);
while(s.hasNext()) {
String[] line = s.nextLine().split(" ");
print.println(String.join(" ", Convert(line)));
}
s.close();
print.close();
}
private static String[] Convert(String[] value) throws ParseException {
for (int i = 0; i < value.length; i+=1)
value[i] = ToJulianisch(value[i]);
return value;
}
private static String ToJulianisch(String date) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd");
Date d = sdf.parse(date);
Calendar c = Calendar.getInstance();
c.setTime(d);
int actDay = c.get(Calendar.DAY_OF_MONTH);
int actMonth = c.get(Calendar.MONTH) + 1 ;
int actYear = c.get(Calendar.YEAR);
actDay -= 13;
if(actDay - 13 < 1) {
actMonth -= 1;
if(actMonth < 1) {
actMonth = 12;
actYear -= 1;
}
Calendar k = Calendar.getInstance();
k.set(Calendar.YEAR, actYear);
k.set(Calendar.MONTH, actMonth - 1);
actDay = k.getActualMaximum(Calendar.DAY_OF_MONTH) + actDay;
}
return String.format("%s-%s-%s", actYear, actMonth, actDay);
}
You are subtracting 13 from actDay twice, first in actDay-=13 and again for if(actDay - 13 < 1). Inside the if block, you then add the value which is less than 14 to the number of days per month, resulting in overflowing the day of month.
If you simply want to subtract 13 days from the given date, you should use c.set(Calendar.DAY_OF_MONTH,actDay-13). This will handle the subtraction correctly inside the Calendar object and you can then use
actDay = c.get(Calendar.DAY_OF_MONTH);
int actMonth = c.get(Calendar.MONTH) + 1 ;
int actYear = c.get(Calendar.YEAR);
return String.format("%s-%s-%s", actYear, actMonth, actDay);
About some mistakes in your algorithm, see the answer of Heikki Mäenpää. I have also seen another mistake, namely a wrong pattern "yyyy-mm-dd" where "mm" stands for minutes (use "MM" for months).
But in general, you seem to try to reinvent the wheel. Even the old java.util.Calendar-API has a built-in way for the transformation from a gregorian to a julian calendar date, see my solution which is valid even for any date in the past with respect to cutover.
Your solution is only valid for dates where the distance between gregorian and julian calendar is 13 days (which is not true in the past, at the time of Pope Gregor's reform, there were only 10 days cut off).
public static void main(String[] args) throws ParseException {
String input = "2017-10-24";
System.out.println("Old API => " + toJulianisch(input)); // 2017-10-11
}
private static String toJulianisch(String date) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
GregorianCalendar gcal = new GregorianCalendar();
gcal.setTimeZone(TimeZone.getTimeZone("GMT"));
gcal.setGregorianChange(new Date(Long.MIN_VALUE));
sdf.setCalendar(gcal);
Date d = sdf.parse(date);
gcal.setGregorianChange(new Date(Long.MAX_VALUE));
gcal.setTime(d);
return sdf.format(d);
}
As you can see, the old API-stuff even forces you to set the timezone to a fixed offset to avoid any possible timezone clutter. This is necessary because java.util.Calendar and java.util.Date are not real calendar dates but instants/moments.
Side notice:
I have written a time library (Time4J) which can even handle any historic date equal if it was gregorian or julian (or even swedish), equal when the historic year started (was in most cases not the first of January!) etc. Maybe it is overkill for your problem but I mention it for the case you really want to operate with true historic calendar dates.
I have an application that plugs into the Google Fit Api and returns the steps for the last 7 days, the method is below. As the screen shot shows though I wish to add the day to the step count.
I have tried many options to take away one day at a time for the 7 loop but had no luck, it just says the same day. Any help would be great thank you.
private void dumpDataSet(DataSet dataSet) {
Log.i(TAG, "Data returned for Data type: " + dataSet.getDataType().getName());
DateFormat dateFormat = DateFormat.getTimeInstance();
int i = 0;
for (DataPoint dp : dataSet.getDataPoints()) {
for(Field field : dp.getDataType().getFields()) { //loop 7 times
int test = dp.getValue(field).asInt();
String weekSteps= String.valueOf(test); //get weekday steps one at a time
SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
Calendar cal = Calendar.getInstance();
String weekday = sdf.format(cal.getTime());
String weekStepsFinal= weekSteps + " steps on " + weekday; //set Textfield to steps and the day
FeedItem item = new FeedItem();
item.setTitle(weekStepsFinal);
feedItemList.add(item);
}
}
}
There are 7 datasets btw.
If by "take away one day at a time" means that you want the days going backwards, then here's how:
SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
System.out.println("Last 7 days (starting today):");
Calendar cal = Calendar.getInstance(); // Initialized to today/now
for (int i = 0; i < 7; i++) {
System.out.println(" " + sdf.format(cal.getTime()));
cal.add(Calendar.DAY_OF_MONTH, -1); // Update to previous day at same time-of-day
}
OUTPUT
Last 7 days (starting today):
Monday
Sunday
Saturday
Friday
Thursday
Wednesday
Tuesday
This will subtract 7 days from the calendar to get you the date 7 days ago:
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, -7).
To subtract one day use the following code :
int DAY_IN_MILLIS = 1000 * 60 * 60 * 24;
Date currentDate = new Date();
long previousDay = currentDate.getTime()-DAY_IN_MILLIS;
SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
String day = sdf.format(previousDay);