Java Fiscal Year Week Counter - java

I've been all up night trying to figure this out, but nothing I try seems to work. Let say the Fiscal year starts on 10/01 of every year, for example the fiscal year started on 10/01/2012 making this week number 30. I can't seem to find the code that returns the appropriate week number.
The closest I've gotten is this code below which returns week number 16 starting from Jan.
public String getCurrentWeek() {
GregorianCalendar current = new GregorianCalendar(getCalendar().get(Calendar.YEAR),
getCalendar().get(Calendar.MONTH), getCalendar().get(Calendar.DATE));
return Integer.toString(current.get(Calendar.WEEK_OF_YEAR));
}

I believe:
private static final int LENGTH_OF_WEEK = 7 * 24 * 60 * 60 * 1000;
public static int weekOf(Calendar yearStart, Calendar date) {
long millisElapsed = date.getTimeInMillis() - yearStart.getTimeInMillis();
int weeksElapsed = (int) (millisElapsed / LENGTH_OF_WEEK);
return weeksElapsed + 1;
}
Should do it.

Related

How to calculate relative time spans using Java (code converting problem)? [duplicate]

This question already has answers here:
Java 8: Difference between two LocalDateTime in multiple units
(11 answers)
Closed 2 years ago.
I decided to give myself a challenge on Java that implements this question's achievement.
The things I have to do is get LocalDateTime, convert the same code from the linked question's answers, then receiving a string from the function.
Here's what I've done so far:
public static String relTime(LocalDateTime now)
{
// accepted answer converted to Java
const int min = 60 * SECOND;
const int hour = 60 * MINUTE;
const int day = 24 * HOUR;
const int mon = 30 * DAY;
// still don't know how to convert this method
var ts = new TimeSpan(DateTime.UtcNow.Ticks - yourDate.Ticks);
double delta = Math.Abs(ts.TotalSeconds);
if (delta < 1 * MINUTE)
return ts.Seconds == 1 ? "one second ago" : ts.Seconds + " seconds ago";
if (delta < 2 * MINUTE)
return "a minute ago";
if (delta < 45 * MINUTE)
return ts.Minutes + " minutes ago";
if (delta < 90 * MINUTE)
return "an hour ago";
if (delta < 24 * HOUR)
return ts.Hours + " hours ago";
if (delta < 48 * HOUR)
return "yesterday";
if (delta < 30 * DAY)
return ts.Days + " days ago";
if (delta < 12 * MONTH)
{
int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));
return months <= 1 ? "one month ago" : months + " months ago";
}
else
{
int years = Convert.ToInt32(Math.Floor((double)ts.Days / 365));
return years <= 1 ? "one year ago" : years + " years ago";
}
}
The only problem that I should encounter is from var ts = new TimeSpan(DateTime.UtcNow.Ticks - yourDate.Ticks);.
Although I read 2 questions from Stack Overflow finding equivalents of TimeSpan and Ticks, I baely have any ideas how to properly convert the line of code. Also, I have to get a double which will need math.abs() to get TotalSeconds which I can't really find a proper way to deal with either, but I did find ZoneOffset.ofTotalSeconds and still don't know how to deal with it.
So how can I convert this properly?
var ts = new TimeSpan(DateTime.UtcNow.Ticks - yourDate.Ticks);
double delta = Math.Abs(ts.TotalSeconds);
You need to gain a deeper understanding of what this method actually does. Literally translating code from C# to Java won't give you a good solution and gets you stuck on language-specific details.
The two lines basically calculate the (absolute) difference in seconds of a timestamp to the current time. This can be written in Java as follows:
Duration duration = Duration.between(LocalDateTime.now(), timestamp);
long delta = duration.abs().getSeconds();
I'm just addressing your actual question here on how to transform these two lines. The provided snippet is not valid Java code and some parts are missing. delta is the difference in seconds which does not necessarily need to be a double. The argument you pass to your method should be named anything else than now because this is the timestamp you want to compare to the current time inside the method.
You could use SimpleDateFormat to create a nice display format (use something like "HH hours, mm minutes and ss seconds ago" for the format (not sure if this exact example works)). You could also use Instant to get the current time, and you can use Instant.now().minusSeconds(Instant.now().minusSeconds(seconds).getEpochSeconds()) for the time difference (or just use System.currentTimeMillis() and multiply by 1000).
Alternatively, you could use Duration and write a custom display format using getSeconds() and getHours() etc.

DatePicker: Only select Mondays

I am currently using the DatePicker in Android to let the user select a date. Is there a possibility to only allow the user to select Mondays and disable all other days for selection? I did not find anything in the Documentation.
Currently I am using this to show the DatePicker:
DatePickerDialog datePickerDialog = new DatePickerDialog(AddAppointment.this,
new DatePickerDialog.OnDateSetListener() {
#Override
public void onDateSet(DatePicker view, int year,
int monthOfYear, int dayOfMonth) {
// Do stuff with the info
}
}, setYear, setMonth, setDay);
datePickerDialog.show();
You can use this library Material Date Time Picker, here you can set an option to show specific dates, For Example:
datePicker.setSelectableDays(Calendar[] days)
And pass the array of Calendar as a parameter which contains all the selectable date.
for finding monday array you can use this logic:- Get all Fridays in a date Range in Java
You can calculate the calendar week of the chosen date or calculate the most recent Monday using one of the methods below. They are commented, so I keep the text short.
public class ExampleDateCalculation {
public static void main(String[] args) {
int dayOfMonth = 4;
int monthOfYear = 3;
int year = 2018;
// create a java.time.LocalDate of the given integers
LocalDate localDate = LocalDate.of(year, monthOfYear, dayOfMonth);
// calculate the calendar week of it
int calendarWeekTheLocalDateIsIn = getCalendarWeek(localDate);
// calculate the last Monday before this date
LocalDate lastMonday = getLastFrom(DayOfWeek.MONDAY, localDate);
// create a formatter for your locale
DateTimeFormatter germanDateFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
System.out.println(localDate.format(germanDateFormatter)
+ " is in calendar week "
+ calendarWeekTheLocalDateIsIn
+ " of the system locale and the last Monday before was at "
+ lastMonday.format(germanDateFormatter));
}
/**
* <p>
* Gets the calendar week number of the given {#link LocalDate} based on the
* {#link Locale} of the operating system.
* </p>
*
* #param localDate the date of the day
* #return the calendar week number the day is in
*/
public static int getCalendarWeek(LocalDate localDate) {
WeekFields weekFields = WeekFields.of(Locale.getDefault());
return localDate.get(weekFields.weekOfWeekBasedYear());
}
/**
* <p>
* Gets the date of the last given weekday or day of week starting from the
* weekday of the given date. The method calculates the date of the nearest
* weekday chronologically backwards.
* </p>
* <p>
* <strong>For example:</strong><br>
* If the weekday of the given date is a Monday and the given day of week is a
* Tuesday, then this method will return the date of the Tuesday before today,
* which is 6 days back in the past.
* </p>
*
* #param weekday the day of week whose date is to be determined
* #param from the date to start from calculating backwards
* #return the date of the last given day of week starting from the given date
*/
public static LocalDate getLastFrom(DayOfWeek weekday, LocalDate from) {
DayOfWeek fromWeekday = from.getDayOfWeek();
int fromWeekdayValue = fromWeekday.getValue();
int weekdaysValue = weekday.getValue();
int daysToSubtract = 0;
/*
* Calculate the days to go back and be beware of negative values by means of
* case differentiation. Get the positive difference by subtracting the smaller
* value from the larger one and subtract a week if the result would be 0.
*/
if (fromWeekdayValue < weekdaysValue) {
daysToSubtract = 7 - (weekdaysValue - fromWeekdayValue);
} else if (fromWeekdayValue > weekdaysValue) {
daysToSubtract = fromWeekdayValue - weekdaysValue;
} else {
daysToSubtract = 7;
}
return from.minusDays(daysToSubtract);
}
}
If you want the user to only see calendar weeks or Mondays, follow the suggestions given in Uday Nayak's answer.
If anyone finds errors in or knows disadvantages of this code, please let me know.
You can try to do it little bit differently. First, change font color of days user don't want to pick (all except Mondays) and than filter active day selected and disable functionality until Monday is selected.

Find Day of Week Without Using Calendar function in Java

I need to find the day of the week (i.e. Monday, Tuesday...) given MM-DD-YYYY. So basically what java calendar would do, but without using java calendar.
It is possible, though unusual, to compute a number that corresponds to the day of the week from a calendar date.
In brief, you will first need to calculate a serial date number from the calendar date, i.e. a number that is a continuous count of days that have elapsed since a certain fixed point in time (informally called 'the epoch'). The most commonly encountered serial date scheme encountered in modern computing is Posix Time, which has an epoch date of Jan 1, 1970 at midnight UTC.
You will need to decide what level of precision is needed for this calculation, eg. whether you will need to account for the Julian Calendar (used in most of Europe before the Gregorian Calendar reform by Pope Gregory in 1584), whether to correct for century days, etc.
Several algorithms are available to arithmetically convert a calendar date to a serial date number with a given epoch. Historically, the most commonly used epoch for these calculations has been the Julian Day number system (not to be confused with the Julian Calendar), which counts days from November 24, 4714 BC in the proleptic Gregorian calendar. Below is Java code which implements one such algorithm published by Jean Meeus in his book "Astronomical Algorithms, 2nd Ed." This algorithm computes a Julian Day number and assumes that days are exactly 86400 seconds in length, accounts for the general Gregorian Reform, and accounts for century and leap days:
public class JulianDay {
private static final int YEAR = 0;
private static final int MONTH = 1;
private static final int DAY = 2;
private static final int HOURS = 3;
private static final int MINUTES = 4;
private static final int SECONDS = 5;
private static final int MILLIS = 6;
:
:
// Converts a timestamp presented as an array of integers in the following
// order (from index 0 to 6): year,month,day,hours,minutes,seconds,millis
// month (1-12), day (1-28 or 29), hours (0-23), min/sec (0-59) to a
// Julian Day Number.
// For clarity and simplicity, the input values are assumed to be well-formed;
// error checking is not implemented in the snippet.
public static double toJD(int[] ymd_hms) {
int y = ymd_hms[YEAR];
int m = ymd_hms[MONTH];
double d = (double) ymd_hms[DAY];
d = d + ((ymd_hms[HOURS] / 24.0) +
(ymd_hms[MINUTES] / 1440.0) +
(ymd_hms[SECONDS] / 86400.0) +
(ymd_hms[MILLIS] / 86400000.0));
if (m == 1 || m == 2) {
y--;
m = m + 12;
}
double a = Math.floor(y / 100);
double b = 2 - a + Math.floor(a / 4);
return (Math.floor(365.25 * (y + 4716.0)) +
Math.floor(30.6001 * (m + 1)) +
d + b - 1524.5);
}
}
Once you have a serial date number, it is straightforward to compute the day of the week from the remainder when the date number is divided by 7 (the number of days in a week).
If you are talking about simply avoiding the Calendar Object then you could use the Date Object (deprecated) but still works and call setMonth, setYear, and setDate to get the desired date. You then have to use a DateFormatter to get your desired output. I used a SimpleDateFormat and the E specifier to get the day of the week.
Date dNow = new Date();
SimpleDateFormat ft = new SimpleDateFormat ("E");
System.out.println("Current Date: " + ft.format(dNow));
This outputs the current day of the week "Sun", "Sat", etc..
This link will help with the formatting https://www.tutorialspoint.com/java/java_date_time.htm
java.time
Using the java.time classes that supplant the troublesome old date-time classes. The LocalDate class represents a date without a time-of-day and without a time zone.
DayOfWeek dow =
LocalDate.parse(
"01-23-2016" ,
DateTimeFormatter.ofPattern( "MM-dd-uuuu" )
).getDayOfWeek()
That code returns a DayOfWeek enum object. From there you can interrogate for:
Integer number, 1-7 for Monday-Sunday
Localized name of the day.
Example code.
int dowNumber = dow.getValue() ;
String dowName = dow.getDisplayName(
TextStyle.FULL ,
Locale.CANADA_FRENCH ) ; // Or Locale.US, Locale.ITALY, etc.
TIP: Pass around the DayOfWeek objects themselves in your own code, rather than internally track the day-of-week as a number or string. This makes your code more self-documenting, ensures valid values, and provides for type-safety.
I was looking for the answer myself and found another answer based on Zeller's algorithm:
// d = day in month
// m = month (January = 1 : December = 12)
// y = 4 digit year
// Returns 0 = Sunday .. 6 = Saturday
public int dow(int d, int m, int y) {
if (m < 3) {
m += 12;
y--;
}
return (d + int((m+1)*2.6) + y + int(y/4) + 6*int(y/100) + int(y/400) + 6) % 7;
}
Source: here

Minus date calculation with GWT

Here is my try to do date minus for GWT:
Date from = new Date();
Date to = new Date();
if(filter.equals(DATE_FILTER.PAST_HOUR)){
minusHoursToDate(to, 1);
} else if(filter.equals(DATE_FILTER.PAST_24_HOURS)){
minusHoursToDate(to, 1 * 24);
} else if(filter.equals(DATE_FILTER.PAST_WEEK)){
minusHoursToDate(to, 1 * 24 * 7);
} else if(filter.equals(DATE_FILTER.PAST_MONTH)){
minusHoursToDate(to, 1 * 24 * 7 * 4);
} else if(filter.equals(DATE_FILTER.PAST_YEAR)){
minusHoursToDate(to, 1 * 24 * 7 * 4 * 12);
}
public static void minusHoursToDate(Date date, int hours){
date.setTime(date.getTime() - (hours * 3600000));
}
The problem I see here is with the calculation in terms of month and year. As months is not always 4-week aligned and a year is also affected.
What could be the best calculation for subtracting month & year?
Since java.util.Calendar is unsupported in GWT because of the complexity needed for its implementation, the final JS size, etc, I would go with a simple and lightweight solution based on JS.
Apart from the java Date implementation, in GWT we have the JsDate wrapper which includes all the methods available in the native JS date, so subtracting a month or a year should be as simpler as:
int months = -2;
int years = -3;
JsDate j = JsDate.create(new Date().getTime());
j.setMonth(j.getMonth() + months);
j.setFullYear(j.getFullYear() + years);
Date d = new Date((long)j.getTime());
You can do the same to manipulate other units:
getDate() Returns the day of the month (from 1-31)
getDay() Returns the day of the week (from 0-6)
getFullYear() Returns the year (four digits)
getHours() Returns the hour (from 0-23)
getMilliseconds() Returns the milliseconds (from 0-999)
getMinutes() Returns the minutes (from 0-59)
getMonth() Returns the month (from 0-11)
getSeconds() Returns the seconds (from 0-59)

Part two: speeddating object

public class Dating
{
// Note: this class has no instance variables!
/**
* Creates an empty Dating object so that you can call the methods
*/
public Dating()
{
// Empty constructor
}
/**
* Computes and returns the next year in which New Year's Day will
* fall on the same day of the week as in a given year
* #param theYear the given year
* #return the next year in which New Year's day is the same day
* of the week as in parameter theYear
*/
public int newYears(int theYear)
{
// TO DO: write body of this method here
}
/**
* Computes and returns the Date on which Election Day will fall
* in the USA for a given year.
*
* NOTE: By law, Thanksgiving Day is the first Tuesday after the first
* Monday in November.
*
* #param year the year for which to compute the date of Election Day
* #return the Date of Election Day for the specified year
*/
public Date electionTime(int year)
{
INSERT CODE HERE
}
I feel like I got the electionTime part correct but I am confused as in to where to begin for newYears. Any suggestions? I'm uncertain how to put together a code that would calculate not only when the date is but when it will happen again. I was not given a specific year to start with either.
/*
* Computes and returns the next year in which New Year's Day will
* fall on the same day of the week as in a given year.
*/
public int newYears(int year)
{
// First, find out what day of the week it falls on in year X
Calendar calendar = new GregorianCalendar(); // create a calendar object
calendar.set(year, 0, 1); // calendar.set([year], January, 1st)
int day = calendar.get(Calendar.DAY_OF_WEEK); // store this value for later
// The code between the curly braces below will be executed 30 times,
// the first time i = 1, the second i = 2, third i = 3, etc...
for(int i = 1; true; i++)
{
calendar.set(year + i, 0, 1); // set the calendar to the next year
if(calendar.get(Calendar.DAY_OF_WEEK) == day) // compare to the value we stored earlier, and if it's the same day...
{
return year + i; // we have the correct year!
}
}
}
EDIT
Okay I'm going overboard here but I must follow the calling of my inner geek.
I took a for loop and looped through and ran a bunch of sequential years through the function, subtracted to find the difference, and got this table:
in | out | difference
2004 2009 5
2005 2011 6
2006 2012 6
2007 2018 11
2008 2013 5
2009 2015 6
2010 2016 6
2011 2022 11
2012 2017 5
2013 2019 6
2014 2020 6
2015 2026 11
There's a very clear pattern that repeats every four years (because of leap year I suppose). Using this, we can write a sneaky/condensed version of this function:
public int sneakyNewYears(int year)
{
int diff = year % 4;
int add = -1;
if(diff == 0) add = 5;
if(diff == 1) add = 6;
if(diff == 2) add = 6;
if(diff == 3) add = 11;
return year + add;
}
This works fine for 98.6% percent of years, but testing this 'sneaky' function against the working function shows that there are a few years that this doesn't work for, for some odd reason... These years: 1575, 1577, 1578, 1579, 1580, 1581, 1582, 1691, 1695, 1696, 1697, 1698, 1699, 1700, 1791, 1795, 1796, 1797, 1798, 1799, 1800, 1891, 1895, 1896, 1897, 1898, 1899 and 1900.
Anyway.

Categories

Resources