Android convert double to duration - java

I am trying to convert an excel formula into Kotlin code. But I am facing issue in converting a double into duration. The Excel displays in duration format. How do I convert to Duration format? I cant use Duration as API level is less than 26.
The result in
Excel Duration format - 0:47:22
Excel Number format - 0.03288861121
I am able to get it in the number format. But unable to convert it into time duration.

I am unsure whether the following is the best solution. You may be able to get something better from Excel somehow. In any case it works.
double durationDoble = 0.03288861121;
Duration dur = Duration.ofNanos((long) (durationDoble * TimeUnit.DAYS.toNanos(1)));
System.out.println(dur);
This prints
PT47M21.576008544S
If you are not used to the Duration class and/or ISO 8601 format, it may look a bit funny, but it means 47 minutes 21.576 seconds, so if rounded to whole seconds it agrees with what you expected.
I cant use Duration as API level is less than 26.
Yes, you can use Duration from java.time (the modern Java date and time API) in API levels less than 26. Add ThreeTenABP to your Android project and make sure to import org.threeten.bp.Duration.
Links
Oracle tutorial: Date Time, explaining how to use java.time.
ThreeTen Backport project (ThreeTen for JSR-310, where java.time was first described)
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
Java Specification Request (JSR) 310.

Related

Print consecutive dates using hyphen

I have a list of dates in the form of ddMMMyyyy stored in one single string. The dates may or may not be consecutive
I print those dates as individual dates. I want to remove that and use hyphen if the dates are consecutive.
For Example
13Aug2020
15Aug2020 - 18Aug2020
22Aug2020
Instead of
13Aug2020
15Aug2020
16Aug2020
17Aug2020
18Aug2020
22Aug2020
Code used to Print Dates :
mDateView.setText(mDateValue.replace(",", "\n"));
where mDateView is a Textview and mDateValue is the String containing all the dates seperated by Commas
Parse each string into a LocalDate object using a DateTimeFormatter. Search for how (if your search leads to a page using the old and troublesome SimpleDateFormat, avoid that). Create two variables for the start and end of the current interval. Store the first date into both. In a loop over the remaining dates:
If the current date is one day after the end, store it into the end, thus extending the interval by one day.
Otherwise print the current interval, see below for how. Then again store the current date into both start and end.
After the loop terminates, print the current interval.
How to print the current interval: if start and end are equal, print only one of them; otherwise print both with an en-dash between them. In either case format each printed date into the desired format, for example the original format using the same DateTimeFormatter.
To determine whether current date is one day after end, use the plusDays and the isEqual methods of LocalDate.
Question: Doesn’t LocalDate require Android API level 26?
LocalDate is part of java.time, the modern Java date and time API. java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On older Android either use desugaring or the Android edition of ThreeTen Backport. It’s called ThreeTenABP. In the latter case make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Documentation of DateTimeFormatter
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
Java 8+ APIs available through desugaring
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.

Converted unix timestamp with a timezone addition in seconds gives a true local date time on Android emulator but not in real device?

I took a date from a web service in UNIX timestamp. I milltuplied it by 1000L then I added the timezone to it in seconds (also provided by the web service) milltiplied by 1000 to obtain the date according to the country in which the application will run and not the UTC date.
In the emulator the date time provided is correct but when I tested on a real device it provided me the time with 1 hour more which does not correspond to the local time. Where is the problem?
long numberOfsecondsRise = json.getJSONObject("city").getInt("timezone");
long res=(json.getJSONObject("city").getLong("sunrise")*1000L +numberOfsecondsRise*1000) ;
Date rise=new java.util.Date(res);
DateFormat dfa = DateFormat.getTimeInstance();
sunFiled.setText(getResources().getString(R.string.sunrise)+": " + dfa.format(rise));
java.time and ThreeTenABP
Consider using java.time, the modern Java date and time API, for your time work. If for minSDK below API level 26, then through the backport, I will get back to that. First the code:
DateTimeFormatter timeFormatter
= DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM);
long sunriseUnixTs = 1_589_581_234;
ZonedDateTime sunriseApplicationTz = Instant.ofEpochSecond(sunriseUnixTs)
.atZone(ZoneId.systemDefault());
System.out.println("Sunrise: " + sunriseApplicationTz.format(timeFormatter));
Output from this example snippet in my time zone and locale:
Sunrise: 03.50.34
One of the things I find great about java.time is that the code makes it explicit that we are getting the time in the default time zone of the JVM where the application is running.
What went wrong in your code?
Adding the time zone offset of the city you are inquiring about is wrong. A Unix timestamp is independent of time zone. So if you multiply by 1000 and feed to new Date(long), you are getting a Date that holds the correct point in time. If you add a non-zero offset, you are getting a wrong point in time. Your emulator gave you the expected result, why, then? It might be because the offset from JSON was 0 (zero) or because the error was balanced out by the emulator using a different default time zone from what you had expected.
Question: Doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
A question about an Android emulator that seems to be using UTC as its default time zone rather than the time zone of the host operating system: Emulated Android Device shows wrong date (Windows 10)
Date (long date) constructor documentation says:
Allocates a Date object and initializes it to represent the specified number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT.
This means the value is supposed to be in UTC. The time offset in seconds must be applied when formatting the date for display.
long numberOfsecondsRise = json.getJSONObject("city").getInt("timezone");
Date rise = new java.util.Date(json.getJSONObject("city").getLong("sunrise") * 1000L);
int offsetMinutes = numberOfsecondsRise / 60;
String sign = (offsetMinutes < 0 ? "-" : "+");
offsetMinutes = Math.abs(offsetMinutes);
String timeZoneID = String.format("GMT%s%d:%02d", sign, offsetMinutes / 60, offsetMinutes % 60);
DateFormat dfa = DateFormat.getTimeInstance();
dfa.setTimeZone(TimeZone.getTimeZone(timeZoneID));
sunFiled.setText(getResources().getString(R.string.sunrise) + ": " + dfa.format(rise));

Convert API timezone in seconds to GMT timezone. Also convert API temperature to deg celcius

I am getting API weather data from some weather website.
It has provided me timezone as 19800 which I want to convert to GMT + 05:30 but I am not able to do the same.
Also it has given temperatures as 297.58 which I want to convert to deg Celcius.
I tried assuming that given temperature as deg Kelvin and reducing 273 from it but it is not working
I want to be able to convert seconds to time zone and show temp in degree celcius.
Offset conversion using java.time
It’s simple when you know how:
int offsetSeconds = 19_800;
ZoneOffset offset = ZoneOffset.ofTotalSeconds(offsetSeconds);
System.out.println("Offset is " + offset);
Output is:
Offset is +05:30
Next you may use the obtained ZoneOffset object to convert the date and time. The details depend on the format of your date and time.
Temperature conversion
I agree that your temperature looks very much like degrees Kelvin. If so, the formula given in the other answer by #Lt . Null is correct:
double temperatureKelvin = 297.58;
double temperatureCelsius = temperatureKelvin - 273.15;
System.out.println("Temperature is " + temperatureCelsius + " degrees Celsius");
Temperature is 24.430000000000007 degrees Celsius
The many decimals come from floating point math most often being inaccurate. (For accuracy, use BigDecimal instead.) For output to the user you may want to print fewer decimals. If so, format the number using NumberFormat and/or DecimalFormat.
If 24.43 °C disagrees with your expectation, you need to tell us what you had expected instead, at the very least.
Question: Can I use java.time on Android?
Yes, java.time works nicely on older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
For your timezone converter use this
long unix_seconds = 19800;
Date date = new Date(unix_seconds*1000L);
// format of the date
SimpleDateFormat formate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
formate.setTimeZone(TimeZone.getTimeZone("GMT+5:30"));
String dateFinal = formate.format(date);
System.out.println("\n"+dateFinal+"\n");
And finding kelvin to degree just use 297.58K − 273.15 = 24.43°C

DateTime("2019-02-16T10:00:00+08:00") conversion to local date time with offset value

I get the datetime content in the below string format with offset time value from the source system.
2019-02-16T10:00:00+08:00
Where i want to convert that into local date time using the offset value.I tried the below, but not getting the expected result.
DateTime date = new DateTime("2019-02-16T10:00:00+08:00");
-->output == 2019-02-16T02:00:00.000Z (the hour is decreased instead of increasing)
DateTime date = new DateTime("2019-02-16T10:00:00-08:00");
-->output == 2019-02-16T18:00:00.000Z (the hour is increased instead of decreasing).
is there any simple way to the expected output?
Note: I am using Java 1.7
What you are doing is correct. To get the time in your local time zone:
DateTime date = new DateTime("2019-02-16T10:00:00+08:00");
DateTime dateTimeInLocalTimeZone = date.withZone(DateTimeZone.getDefault());
System.out.println(dateTimeInLocalTimeZone);
On my computer in Europe/Copenhagen time zone I got
2019-02-16T03:00:00.000+01:00
As has been said in the comments, +08:00 is the offset that has already been added compared to UTC time. So your string denoted the same point in time as 2019-02-16T02:00:00+00:00. It may also be written as 2019-02-16T02:00:00Z since Z (pronounced “Zulu”) means UTC.
java.time and ThreeTen Backport
If you are not already tied to Joda-Time, you may prefer to use java.time, the modern Java date and time API. The code is similar:
OffsetDateTime sourceDateTime = OffsetDateTime.parse("2019-02-16T10:00:00+08:00");
ZonedDateTime dateTimeInLocalTimeZone = sourceDateTime.atZoneSameInstant(ZoneId.systemDefault());
2019-02-16T03:00+01:00[Europe/Copenhagen]
Question: Can I use java.time on Java 1.7?
Note: I am using Java 1.7
No big problem, java.time just requires at least Java 6. I have run the above code on jdk1.7.0_79.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
Another way to do that :
String dt = "2019-02-16T10:00:00+08:00";
ZonedDateTime zd = ZonedDateTime.parse("2019-02-16T10:00:00+08:00");
System.out.println(zd.toLocalDateTime().plusSeconds(zd.getOffset().getTotalSeconds()));
Output
2019-02-16T18:00

Convert a date of 6 months ago from now, into a String

I've taken all of the answers given on SOF and other websites and tried to do this:
String fromDateTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sssX").format(new DateTime().plusMonths(-6));
But I'm being given the exception:
Exception in thread "main" java.lang.IllegalArgumentException: Cannot format given Object as a Date
What am I doing wrong?
java.time
String fromDateTime = OffsetDateTime.now(ZoneId.systemDefault()).minusMonths(6).toString();
System.out.println(fromDateTime);
Output when running on my computer just now:
2018-08-04T12:45:34.087966+01:00
java.time is the modern Java date and time API and has effectively replaced Joda-Time. From the home page:
Note that Joda-Time is considered to be a largely “finished” project.
No major enhancements are planned. If using Java SE 8, please migrate
to java.time (JSR-310).
In the code I am taking advantage of the fact that the java.time classes’ toString methods produce ISO 8601 format, the format you were asking for. I find it unlikely that the extra decimals on the seconds will pose any problem since thay are allowed within the standard.
Joda-Time
String fromDateTime = new DateTime().minusMonths(6).toString();
Example output:
2018-08-04T12:50:36.071+02:00
new DateTime() only has millisecond precision. You will always get exactly 3 decimals on the seconds.
I gotta use old java libraries, cause I work for a company that uses java version < 8
java.time works nicely on Java 6 and 7 too, and all things being equal I recommend it over Joda-Time. Only if forced to use Java 5, Joda-Time is no doubt the good choice.
In Java 8 and later and on newer Android devices (from API level 26) java.time comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
What went wrong in your code?
Your code can be compiled without signs of errors, but issues a java.lang.IllegalArgumentException: Cannot format given Object as a Date when run. This is because a SimpleDateFormat cannot format a Joda-Time DateTime object. We would of course have expected this to be reported on compile time. But in addition to SimpleDateFormat.format(Date) there is also an overridden format(Object) inherited from Format. It works for formatting either a Date or a Number (for milliseconds since the epoch). This method is the one that the compiler chooses when you pass a DateTime. Which is why there is no compile-time error message.
Tip: When you don’t immediately understand an error message, paste it into your search engine. It will very often lead you to an explanation and a solution. Also in this case.
Links
Joda-Time home page
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
Wikipedia article: ISO 8601
Sister question: Java : Cannot format given Object as a Date.
Try the following:
String fromDateTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sssX").format(new DateTime().minusMonths(6).toDate());
You have to convert the DateTime to a Date before formatting, using the toDate() method will do the job.
API for toDate() and API for minusMonths, I would recommend to you check the API for new methods

Categories

Resources