I have a question. I've never did that before. So how I can to convert time in format, what Google Places Api is giving me, and to get hour of day from that?
From the Google Places API documentation:
periods[] is an array of opening periods covering seven days, starting from Sunday, in chronological order.
Each period contains:
open contains a pair of day and time objects describing when the place opens:
day a number from 0–6, corresponding to the days of the week, starting on Sunday. For example, 2 means Tuesday.
time may contain a time of day in 24-hour hhmm format (values are in the range 0000–2359). The time will be reported in the place’s timezone.
close may contain a pair of day and time objects describing when the place closes. Note: If a place is always open, the close section will be missing from the response. Applications can rely on always-open being represented as an open period containing day with value 0 and time with value 0000, and no close.
Based on this, it's up to you to parse the information and format it appropriately.
Why are you trying to parse out JSON? If you're using Java, stick to Java. You have access to the actual objects. What's the point in using the client services API?
PlaceDetails place = PlacesApi.placeDetails(new GeoApiContext.Builder().apiKey(API_KEY).build(), "insert place id");
for (Period period : place.openingHours.periods)
{
LocalTime time = period.open.time;
}
Related
Problem:
I should parse an RFC3339 date string. It works fine with ISO_ZONED_DATE_TIME:
ZonedDateTime.parse("1985-04-12T23:20:50.52Z", ISO_ZONED_DATE_TIME);
ZonedDateTime.parse("1996-12-19T16:39:57-08:00", ISO_ZONED_DATE_TIME);
Let's say I'll fix a problem of Unknown Local Offset Convention just to not accept these dates.
But I still have a problem with some corner cases like this:
1990-12-31T23:59:60Z
This represents the leap second inserted at the end of 1990.
1990-12-31T15:59:60-08:00
This represents the same leap second in Pacific Standard Time, 8
hours behind UTC."1990-12-31T15:59:60-08:00"
Question:
How can I parse it avoiding to lose any seconds?
Update:
Does it exist any alternative to ZonedDateTime that suits well
RFC3339?
java.time doesn’t offer any direct support for what you want. Just earlier today I wrote this answer that also has a section on parsing a leap second. But what is said there is all there is.
So there’s hand parsing left. I’d try something along these lines: Use a regular expression for detecting whether the second is 60. If so: Substitute it with 59. Parse. Convert to UTC. If the time of day in UTC is 23:59:59, assume there was a valid leap second in the original string; otherwise the string didn’t denote a valid time.
I suggest that in case of a leap second second values up to 60.999999999 are valid. So to detect whether there is a 60 you need to look at what comes after the colon (if any) after the minutes, and not depend on whether there is a fractional part too.
I want to calculate the number of days from the "beginning of time" to a current date. This could be easily achieved with a simple calculation (timestamp / 24 / 60 / 60 / 1000 = daysFromBeginningOfTime) but the twist is that i need to be aware of time zones as well. The timestamp is the same everywhere in the world but when you parse it with the proper time zone then it reflects the differences between locations so using just the timestamp doesn't work and i don't want to handle all the time zone transitions myself.
Example:
if it's 23:30 in London and the day number is 18843 then in Amsterdam it's 0:30 and the day number should be 18844.
I looked at joda.time but didn't really find what i was looking for.
Anyone have any ideas?
The problem appears due to a wrong initial assumption, I think.
The argument the OP makes in his example is not correct. No matter what the clock shows in London or Amsterdam, the time difference to the start of the epoch is - at every point of time - independent of where you are in the world.
Hence, the solution is to parse a given input date to an UTC timestamp and proceed as before.
(Ignoring the point that zero is not "the beginning of time" ... and that the actual time point for the beginning of time is probably unknowable ...)
Here's how to calculate the number of days since "the local-time UNIX epoch in a given timezone"1.
Get hold of the object that represents the local timezone.
Get the timezone's offset from the object
Convert it to milliseconds and add it to the current UTC time.
Calculate the day number as before.
1 - ... whatever that means.
Application: Java + ExtJS
There are a lot of different entity with properties of java.util.Date type: startDate and iesendDate (endDate could be NULL). Both dates could be selected with or without time part (e.g. time part is always persisted, event if it is not selected). For example, like this:
2010-07-01 00:00:00
Possible problems start when user selects endDate without time. For example, period starts on 2010-07-01 and ends on 1010-07-04. Right now in database it is stored like:
startDate="2010-07-01 00:00:00"
endDate="2010-07-04 00:00:00".
So it seems that period ends on the FIRST second of 2010-07-04. But as user assume, that endDate is implicitly included, e.g. period ends on LAST second of 2010-07-04. There are a lot of date comparisons for different periods in the system.
How in this case to store end date properly?
I thought about possible solutions, but all of them seems a bit wrong:
To store time part for end date like this: "2010-07-04 23:59:99". But then seems that end date day is not 24h - but (24h - 0.(9) millisecond), that could be potential problem. Also time part looks quite ugly.
To modify ExtJs component that it will add 1 day to date selected by user on persistance stage and substract 1 day again when this date will be shown to user (except cases when the user explicitly set time part). I don't like here that dates with time part and without it are treated differently.
To save only start date as Date object, and then save length of period in seconds, for example. This approach seems quite good - but a have to rework the whole application and possible it will be no very easy to use different comparisons on end dates.
Just use current one - save non-enclusive end date without time and be very careful during dates comparisons
Could someone explain the most widely used practices to solve such problem?
I've recently changed from your first approach to your second approach.
Approach 1: "2010-07-04 23:59:99" should be "2010-07-04 23:59:59" but anyway it is indeed ugly and technically there is a lost second. Another issue I did have is that I wanted to start one record with the same data/time as another record was stopped. So it was possible to find the successor of a record. And with approach 1 this cannot be done as the time will differentiate 1 second.
Approach 2: The end date will be "2010-07-05" and the query condition will be < endDate instead of <= endDate for approach 1. Here the end date is meaning 'till' or 'until' or 'up to' and not like in approach 1 'up to and including'. For this reason in new projects I do use tillDate or actually I use something like serviceStart / serviceTill.
The disadvantage is indeed to format it -1 day when showing to the user. But for me this makes sense.
Add end date as +1 day of user selected value.
Separate model and presentation
Do separate the stored end time in your database completely from the presentation of the end time to the user.
Store end date and time in database: Since you always store both date and time, you should clearly store the true date and time. If the period end at midnight between July 4 and 5, store this time, so 2010-07-05 00:00:00.
Present to the user: How your user would like to see that end time, I cannot say, and you should ask the users themselves. Maybe they will tell you:
As it is. 2010-07-05 00:00:00.
As 24 hours on the last day of the period, 2010-07-04 24:00:00.
As the last day as date only 2010-07-04 (I consider this unlikely, especially of the start time is not at midnight).
Or something else.
So yes, it’s very likely that you will have to treat end at midnight specially for presentation. It is not nearly as bad as if you had needed to treat it specially in your business logic.
So me and my partner have been working on this project for a while now. We work with dates A LOT in this project, and we recently noticed an issue, and we are rather deep in at this point.
We store our times in SQLlite (Android project) as a formatted string, since a lot of the time they are directly bound to listviews and such.
The problem we noticed, which i found kind of odd, is that that SimpleDateTimeFormat object, when used to format to 24h time (its a medical based project, so 24h time is the convention here) 12:00am-12:59am are formatted to 24:00-24:59, instead of 00:00-00:59...
This isn't too much of an issue until we query the database and order the results by the dates, any data that is between 12:00am and 12:59am will show up at the end of the list, but it should show up at the beginning...
Anyone else encountered this problem? or know a way around it? The best thing possible would be a way to store the data as 00:00 not 24:00.
Cheers
I strongly suspect you're using the wrong pattern. We've got to guess as you haven't posted any code (hint, hint), but I suspect you're using a pattern such as
kk:mm:ss
instead of
HH:mm:ss
Sample code:
import java.util.*;
import java.text.*;
public class Test {
public static void main(String[] args) throws Exception {
SimpleDateFormat broken = new SimpleDateFormat("kk:mm:ss");
broken.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
SimpleDateFormat working = new SimpleDateFormat("HH:mm:ss");
working.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
Date epoch = new Date(0);
System.out.println(broken.format(epoch));
System.out.println(working.format(epoch));
}
}
Additionally, as others have pointed out, you shouldn't be storing your values in string format to start with... avoid string conversions wherever you can, as each conversion is a potential pain point.
Please read this and this about how SQLite stores dates (or doesn't store dates). SQLite doesn't have a "Date" type, so it is stored as a string. You should store your date as an integer (milliseconds), and then you can use date and time functions to pull them out (from the first link).
From the documentation
1.2 Date and Time Datatype
SQLite does not have a storage class set aside for storing dates
and/or times. Instead, the built-in Date And Time Functions of SQLite
are capable of storing dates and times as TEXT, REAL, or INTEGER
values:
TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS"). REAL as Julian
day numbers, the number of days since noon in Greenwich on November
24, 4714 B.C. according to the proleptic Gregorian calendar. INTEGER
as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.
Applications can chose to store dates and times in any of these
formats and freely convert between formats using the built-in date and
time functions.
I prefer INTEGER / Unix time storage, then use the built in date and time functions to format when pulling from DB.
EDIT: Also, this will take care of sorting. I'm guessing your current "sorting" of the dates in SQLite is string based, which is bad mmmmkay.
What is the format string you are passing to your SimpleDateFormat? According to the docs, using 'H' for the hours should get you 0-23, using 'k' should get you 1-24.
I insert some data into Sqlite database and check before insert if record for this day allready exists. To check this I have to see if number of days are >0. For example difference (in days) between 2011-8-6 and 2011-8-5 is 1. How to do this in Java?
EDIT:
As #RayToal mentioned this could be done in database, so I did on that way:
SELECT julianday('now') - julianday(Date(Date)) from VIDEO_HISTORY;
Only problem with this is that it gives me decimal number. For example: 3.3442346529103816
Now I have to decide inside Java if given number is 3 of 4 days.
It code is for app that searches youtube for some term and writes statistical data about daily views into database. User is able to schedule job for example every day in 20:00 o'clock. But then he could decide to reschedule this job in 10:00 o'clock, so program has to understood this like difference is one day. So it's obvious that I have to round to first bigger number. Is there some method for this or I have to write myself?
EDIT2: According to links provided by #Michael-O this is best solution (using JodaTime):
DateTime start = new DateTime(new GregorianCalendar(2011, 8, 4).getTime());
DateTime end = new DateTime(new GregorianCalendar(2011, 8, 8).getTime());
int numberOfDays = Days.daysBetween(start.toDateMidnight(), end.toDateMidnight()).getDays();
System.out.println(numberOfDays);
You may want to consult this tutorial. Moreover you should consider using Joda Time's Period and consult this answer on stackoverflow.
If you want the number of calendar days (a Period in java.time parlance), then use (in Java 8):
import java.time.temporal.ChronoUnit;
import java.time.LocalDate;
ChronoUnit.DAYS.between(LocalDate.parse(from.toString()),LocalDate.parse(to.toString())
(This avoids a subtle bug in Java 8's java.sql.Date API)
If you want a Duration in days (physically elapsed time in 24-hour units), then use Marcelo's approach.