I am currently working on a simple program to create and display timelines for history students and I ran into a problem.
When creating a new event, users have to fill a little form including DatePickers object to select start date and end date for the event. My problem is with date Before Christ or negative date. I can't seem to use them. Hence my questions:
Can LocalDate include dates BC? If so how do you write them? (dd-mm-yyyy) with a minus on the first y?
Can DatePicker allow the selection of BC dates?
Thanks in advance!
Kind regards,
A
getEra
public Era getEra()
Gets the era applicable at this date.
The official ISO-8601 standard does not define eras, however IsoChronology does. It defines two eras, 'CE' from year one onwards and 'BCE' from year zero backwards. Since dates before the Julian-Gregorian cutover are not in line with history, the cutover between 'BCE' and 'CE' is also not aligned with the commonly used eras, often referred to using 'BC' and 'AD'.
Users of this class should typically ignore this method as it exists primarily to fulfill the ChronoLocalDate contract where it is necessary to support the Japanese calendar system.
The returned era will be a singleton capable of being compared with the constants in IsoChronology using the == operator.
Specified by:
getEra in interface ChronoLocalDate
Returns:
the IsoChronology era constant applicable at this date, not null
source: https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html
Related
I need to implement a labor calendar able to count working days and, of course, natural days. The calendar must be able to handle national holidays and these days must be submitted by the user.
So, if I need to calculate the difference between two days the counting must ignore Saturdays, Sundays, and Holidays.
The Java class Calendar, doesn't handle holidays or working days, so I need to make it by myself. I have think two possible ways:
First way:
I could implement a new Day class which would have a boolean isHoliday to check if that is a working day or not, then create a new class with all the methods I'd need to handle/count the days.
Pros:
Easy to handle
I can override/create methods like toString, toDate, etc...
Cons:
Heavy (Maybe?)
My doubt about this approach is how to store it. It'd mean to make 365 objects and store them in a Listor Linked List and that's a lot of data to handle.
Second way:
My second idea is to make it more simple. Create an array of Strings or Dates where I'd store the holidays.
Example new ArrayList<String> freeDays = ["01/01/2019", "05/01/2019", "06/01/2019"...] and with work with it using a new CalendarUtils class or something like that.
Pros:
More readable
Light
Cons:
Hard to work with
For me the first option looks better, however, I don't want to waste memory or use bad practices.
Which option looks better? Are there any third option?
Avoid legacy date-time classes
Never use Date or Calendar classes. Those terribly troublesome old classes are now legacy, supplanted by the java.time classes, specifically Instant and ZonedDateTime. You may find LocalDate helpful too.
Smart objects, not dumb strings
Never use strings to represent date-time within your Java code. Use objects, the java.time classes.
When exchanging date-time values as text, always use the standard ISO 8601 formats. The java.time classes use these formats by default when parsing/generating strings. For a date that would be YYYY-MM-DD such as 2018-01-23.
TemporalAdjuster interface
To skip weekends, use the TemporalAdjuster implementation found in the ThreeTen-Extra project.
nextWorkingDay
previousWorkingDay
Example:
LocalDate // Represent a date-only value, without a time-of-day and without a time zone.
.now( // Capture the current date.
ZoneId.of( "Africa/Tunis" ) // Time zone required. For any given moment the date varies around the globe by zone.
)
.with( // Invoke a `TemporalAdjuster` implementation.
org.threeten.extra.Temporals.nextWorkingDay()
) // Returns a `LocalDate`. Using immutable objects pattern, producing a fresh object based on the values of another while leaving the original unaltered.
To skip holidays, you must write your own code. No two people, companies, or countries share the same definition of holidays.
You’ll need to define your own list of holidays. I suggest writing that as an implementation of TemporalAdjuster for working neatly with the java.time classes. Perhaps nextBusinessDay and previousBusinessDay. That ThreeTen-Extra project mentioned above is open-source, so look to there for code to guide you. And I vaguely recall posting one or more implementations of TemporalAdjuster myself here on Stack Overflow.
You might store those holiday dates in a database for persistence. And represent them at runtime in chronological order as a List< LocalDate >, sorted with Collections.sort and searching with Collections.binarySearch. But beware of thread-safety. You’ll likely need to update that list during runtime. Writing while reading must be protected. Search for more info. And read the excellent book, Java Concurrency in Practice by Brian Goetz et al.
You can combine your holiday-skipping code with weekend-skipping code. Use a search engine to find my Answers on weekend-skipping using EnumSet and DayOfWeek enum. (The search feature built into Stack Overflow unfortunately skews towards Questions while ignoring Answers.)
Search Stack Overflow. All of this has been asked and answered before.
I have a scenario in a current java program where if the user enters a certain date (01/01/1900) in an excel Date field I'm supposed to flag that and clear the value out in the database. In this case since the field is a Date type, I need to pass it to an xml as "" i.e and empty String since I can't just pass null. I'm getting an error because it is expecting a format of "yyyy-MM-dd" to pass to the xml and not "". Of course when setting the Date field to a certain value, I can't just pass an empty String in the setVesselDate() method because it will complain saying it must be in so so format. I have a method that validates the date (handleValidateDate) that returns the sql Date value.
Any recommendation to actually set the date field as "" would be helpful. Below is the code I have:
if (vesselAssignmentObj.getVesselDate().length() > 0)
{
String clearOutDateFlag = "1900-01-01";
String clearField = "";
//below returns a dateformat of yyyy-MM-dd at i
vesselDate = handleValidateDate(vesselAssignmentObj.getVesselDate(), VESSEL_ASSIGNMENTS_VESSEL, i);
if (vesselDate.toString().equals(clearOutDateFlag))
{
vesselAssignmentObj.setVesselDate(String.valueOf(vesselDate.toString().equals(clearField)));
}
else
{
vesselAssignmentObj.setVesselDate(String.valueOf(vesselDate).toString());
}
}
No easy answer.
… I'm supposed to flag that and clear the value out in the database…
Whoever instructed you should have defined what "clear the value out" means.
NULL
Usually in a database "clear the value out" might mean using a NULL value. But nulls bring a bag of hurt, raising ambiguity as to the meaning, affecting sorting and queries in various ways, and carrying ramifications in your app(s) and libraries.
While I generally avoid NULL like the plague (taking Dr. Chris Date’s advice), this may in fact be the best fit for your needs.
Arbitrary date as flag
You could choose an arbitrary date to use as flag that means 'empty' or 'not specified' or 'unknown'. But what date? One commenter suggested 0000-00-00 but this value may exceed the limits of some database’s date data-types. Furthermore, dates around year zero can be problematic because of how different calendaring systems handle the meaning of that period. Furthermore, any date before the adoption of the Gregorian calendar in the West is problematic as we lost some days in transitioning from Julian calendar to Gregorian.
1901-01-01
In a comment you said that a business rules requires dates to be over the year 1900. In that case I would choose 1901-01-01 as my flag date. The trick is making this clear to the entire team and to posterity. Be sure to use well-named constant in your programming, and document well in both your apps and in the database.
1970-01-01
Another common choice of arbitrary date flag is the first of 1970, 1970-01-01. That date is a commonly used epoch reference date used in Unix time and in java.time. This makes that particular date recognizable to many folks in the information trade. But you still need to document thoroughly, as this epoch date is far from the only one: At least a couple dozen other epoch dates have been in widespread usage.
Millenium
Yet another choice could be the date of the new millennium. Unfortunately, that phrase means different dates to different people, in year 2000 or 2001.
The Postgres database uses 2000-01-01 as its epoch. The Apple Cocoa framework, possibly the most widely distributed software in the world, uses 2001-01-01.
Use objects, not strings
You should not be passing strings to/from your database. Use objects instead. The job of your JDBC driver is to mediate between your Java data types and your database types.
Drivers compliant with JDBC 4.2 and later should be able to use java.time types via PreparedStatement::setObject and ResultSet::getObject. If not, fall back to using the java.sql types briefly and immediately convert to/from the java.time types. To convert, look to new methods added to the old classes.
All this JDBC date-time stuff has been covered many times already, so search Stack Overflow for more information. Search for class names Instant, ZonedDateTime, and ZoneId.
I use the Joda time package to calculate durations between two historic instances in times in an Android application/activity. The two instances may for example have happened in the 19th century in Russia (Julian calendar system – before Russia adopted the Gregorian calendar system) and 20th Century western Europe (Gregorian calendar).
The inconvenience is that I now have to choose Julian or Gregorian chronologies based on my knowledge on specific countries actual cutover dates. These individual cutover dates can be found at Wikipedia or in the litterature.
As I see it, there are three solutions to my problems:
1) Look up all the cutover dates for the countries in literature. Then manually punch in the specific cutover date/time for the individual time zones. And use the factory setting in GJChronology.getInstance(zone, factorySettingCutoverDateTimeMillis, 4) where factorySettingCutoverDateTimeMillis is a long containing the milliseconds value of the specific instance in time when the cutover between Julian and Gregorian calendars happened in the specific DateTimeZone zone.
2) Identify where the specific cutover dates eventually are located in Jodatime (or elsewhere accessible in Android), and then make use of them.
3) Use the dafault GJChronology.getInstance(zone, null, 4) that specifies the default date in October 1582 (that is correct for many countries, but not all).
Solution 1) is possible, but require some manual labour to implement. Solution 2 is best, while solution 3) is where I am now using the default in the GJChronology or picking Julian or Gregorian if I know the particular calendar system used at that time.
I hope for help to arrive at solution 2) or get help to direct me to the best compiled cutover date/time list online to save work implementing solution 1). Thanks for your help.
I don't believe that Joda Time has that information within it - I certainly haven't come across it. The idea of a "country" doesn't really exist in Joda Time, and the cutover is not necessarily associated with a time zone either. That rules out solution 2, I believe.
I don't know of any official source of this information - I don't believe it's in the Unicode CLDR, for example... but could this page be useful to you? I have no idea of its reliabilty of completeness, but I guess it's a start :)
In some system I have to operate on dates which may have limited precission (like month and year only or year only), e.g. "2001" or "January 2011". I need to know not only date, but the presission (day, month or year) as well.
I can do this by hand, but does anybody know any java library which supports this type of dates with variable precission?
I would consider using a well known library such as Joda Time and model each "date" as a time span (Interval in Joda Time).
After all, that's sort of what it is; "2001" is not actually a specific point in time, but a period.
The span / length of the interval would reveal the precision, and the starting point of the period could be interpreted as the point in time at which the "date occurred".
Lookup SimpleDateFormat and Date. These both classes should be sufficient for your use case.
Reference: SimpleDateFormat
why not use the Calendar class ?
Use Joda Time which already has support for a YearMonth type (amongst other things) - you can create your own Year type if you want, based on similar code.
This is a follow up question (and possibly should have been asked before it) to this question:
Subclasses of java.util.Calendar.
I'm internationalising a large Java app that uses dates fairly regularly since a lot of the data has dates associated with it. One of the first languages that it will be translated into is Arabic.
Currently I'm having trouble contacting an Arabic speaking person so am asking you; will business users understand and be familiar with the Gregorian calendar?
I guess that the answer could depend on the data which is only supported in one locale (chosen at time of setup), despite being stored as a timestamp.
If data is localised for a locale that commonly uses the Gregorian calendar, but the user is Arabic, do I display the data dates using the Hijri calendar system or will they be familiar with the Gregorian calendar system? And vice-versa?
It depends on how "interationalized" the context of your application is.
If it is some international business application, i.e. for handling imports and exports your customers most likely would expect a Gregorian calendar. Before the Euro (€) many European businesses used the Dollar ($) as default currency, because it simplified many things. The same could apply to the calendar.
On the other hand a highly localized application, like a TV schedule or birthday reminder, you should most certainly use the local calendar.
In other words: Ask you customer or make it user-defineable.
One other thing: Even if most of your users would know the Gregorian calendar, you should think of whether a localized calendar would be an improvement. A few years ago when the whole IT marked was undisputably dominated by the US I was thrilled whenever I used an application which supported Umlauts (äöü). The same concept might give you an edge over your competitors. Delight your customers :)
And as always: Use Joda time.
First, concerning dates use Joda time if you can.
Second, I believe the Gregorian calendar is used for international business and the Islamic calendar is used for purposes of religious holidays & ceremonies; depending on the country, the Islamic calendar may also be the "official" calendar.
For example, in Saudi Arabia the official calendar is indeed the Islamic calendar but by law they do maintain dual calendars for purposes of international business.