I have epoch time and I am trying to get the day of the week. For example lets say I get time as 16/04/2015 16:03:56. I want to find out what day is 16th (Monday, Tuesday... )
scala> import java.text.SimpleDateFormat
import java.text.SimpleDateFormat
scala> import java.util.{TimeZone, Locale}
import java.util.{TimeZone, Locale}
scala> dateFormat.setTimeZone(TimeZone.getTimeZone("Etc/UTC"))
scala> val dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss", Locale.US)
Following code will return time with the date:
scala> dateFormat.format("1429200236824".toLong)
res2: String = 16/04/2015 16:03:56
From this how can I obtain what day is 16th, (above example is in scala but its same is java too)
Java 8 Solution
You should use the new Java 8 DateTime API. It is based on JodaTime and is much nicer to work with. Here is a good overview of the API (http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html).
Using the new API, the following code will get your answer.
Welcome to Scala version 2.11.7 (OpenJDK 64-Bit Server VM, Java 1.8.0_65).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import java.time.ZoneId
import java.time.ZoneId
scala> import java.time.ZonedDateTime
import java.time.ZonedDateTime
scala> import java.time.Instant
import java.time.Instant
scala> ZonedDateTime.ofInstant(Instant.ofEpochMilli("1429200236824".toLong), ZoneId.of("Etc/UTC")).getDayOfWeek
res0: java.time.DayOfWeek = THURSDAY
scala>
Java 7 Standard Library Solution
If you must use Java 7 (you shouldn't use Java 7) then this will get you the day of the week in terms of an Int (1=Sunday, 7=Saturday).
Welcome to Scala version 2.11.7 (OpenJDK 64-Bit Server VM, Java 1.8.0_65).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import java.util.TimeZone
import java.util.TimeZone
scala> import java.util.Calendar
import java.util.Calendar
scala> val c = Calendar.getInstance
c: java.util.Calendar = java.util.GregorianCalendar[time=1445886305100,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/Denver",offset=-25200000,dstSavings=3600000,useDaylight=true,transitions=157,lastRule=java.util.SimpleTimeZone[id=America/Denver,offset=-25200000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2015,MONTH=9,WEEK_OF_YEAR=44,WEEK_OF_MONTH=5,DAY_OF_MONTH=26,DAY_OF_YEAR=299,DAY_OF_WEEK=2,DAY_OF_WEEK_IN_MONTH=4,AM_PM=1,HOUR=1,HOUR_OF_DAY=13,MINUTE=5,SECOND=5,MILLISECOND=100,ZONE_OFFSET=-25200000,DST_OFFSET=3600000]
scala> c.setTimeZone(TimeZone.getTimeZone("Etc/UTC"))
scala> c.setTimeInMillis("1429200236824".toLong)
scala> c.get(Calendar.DAY_OF_WEEK)
res2: Int = 5
scala>
Joda-Time
As requested here is a Joda-Time version. Please be aware that the Joda-Time developers are asking you to use the Java 8 Standard Library instead. Once they end of life Joda-Time you will be in danger of using a library that will not get bug fixes, i.e. You should use Java 8.
Welcome to Scala version 2.11.7 (OpenJDK 64-Bit Server VM, Java 1.8.0_65).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import org.joda.time.{DateTimeZone, DateTime}
import org.joda.time.{DateTimeZone, DateTime}
scala> new DateTime("1429200236824".toLong, DateTimeZone.forID("Etc/UTC")).dayOfWeek.getAsText
warning: Class org.joda.convert.FromString not found - continuing with a stub.
warning: Class org.joda.convert.ToString not found - continuing with a stub.
warning: Class org.joda.convert.ToString not found - continuing with a stub.
warning: Class org.joda.convert.FromString not found - continuing with a stub.
warning: Class org.joda.convert.ToString not found - continuing with a stub.
res0: String = Thursday
scala>
Related
When you use scala repl simple call System.loadLibrary("opencv_410") (in case you are trying to load libopencv_410.so) does not make you able to use native library. If you try to create some object of the class with JNI calls it will tell you --- java.lang.UnsatisfiedLinkError, as if no library was loaded.
Welcome to Scala 2.12.8 (OpenJDK 64-Bit Server VM, Java 1.8.0_201).
Type in expressions for evaluation. Or try :help.
scala> System.loadLibrary(org.opencv.core.Core.NATIVE_LIBRARY_NAME)
scala> new org.opencv.core.Mat()
java.lang.UnsatisfiedLinkError: org.opencv.core.Mat.n_Mat()J
at org.opencv.core.Mat.n_Mat(Native Method)
at org.opencv.core.Mat.<init>(Mat.java:26)
... 24 elided
scala>
Solution with no explanation is provided.
To load native library you should load it for the class scala.tools.nsc.interpreter.IMain. As two argument method loadLibrary0 of Runtime class is not accessible from our scope we use reflection to invoke it.
Welcome to Scala 2.12.8 (OpenJDK 64-Bit Server VM, Java 1.8.0_201).
Type in expressions for evaluation. Or try :help.
scala> val loadLibrary0 = Runtime.getRuntime.getClass.getDeclaredMethods()(4)
loadLibrary0.setAccessible(true)
loadLibrary0.invoke(Runtime.getRuntime, scala.tools.nsc.interpreter.ILoop.getClass, "opencv_java410")
loadLibrary0: java.lang.reflect.Method = synchronized void java.lang.Runtime.loadLibrary0(java.lang.Class,java.lang.String)
scala>
scala> res1: Object = null
scala> new org.opencv.core.Mat()
res2: org.opencv.core.Mat = Mat [ 0*0*CV_8UC1, isCont=false, isSubmat=false, nativeObj=0x7f5162f2a1f0, dataAddr=0x0 ]
In my Java 8u51 application, I need to use Thailand locale.
However, I would like to use Gregorian Calendar instead of Buddhist Calendar.
I tried to replace java.util.Calendar 's CalendarProvider with SPI, but it has not worked out.
import java.security.AccessController;
...
import sun.util.locale.provider.LocaleProviderAdapter;
import sun.util.spi.CalendarProvider;
...
public static void main(String[] args) {
try {
System.out.println(AccessController.doPrivileged(new sun.security.action.GetPropertyAction("java.locale.providers")));
Locale l = Locale.getDefault(Locale.Category.FORMAT);
CalendarProvider provider = LocaleProviderAdapter.getAdapter(CalendarProvider.class, l).getCalendarProvider();
provider.getInstance(TimeZone.getDefault(), l);
LocaleProviderAdapter.getAdapterPreference().forEach(o -> System.out.printf("Adapter: %s%n", o));
System.out.printf("Provider: %s%n", provider.getClass());
System.out.printf("Availables: %s%n", Calendar.getAvailableCalendarTypes());
System.out.printf("Calendar: %s%n", Calendar.getInstance().getClass());
}
...
src/META-INF/services/sun.util.spi.CalendarProvider is as follows.
sun.util.locale.provider.AlwaysGregorianCalendarProviderImpl
Omit the source of AlwaysGregorianCalendarProviderImpl.
result,
$ java -jar Sample.jar -Djava.locale.providers=SPI -Duser.language=th -Duser.country=TH
SPI
Adapter: SPI
Adapter: FALLBACK
Provider: class sun.util.locale.provider.CalendarProviderImpl
Availables: [gregory, buddhist, japanese]
Calendar: class sun.util.BuddhistCalendar
Buddhist Calendar will be used.
How can I change it to a Gregorian calendar?
Self reply late.
The SPI implementation by Sun did not allow external expansion. It also checks the filenames of the divided inner classes.
Although I did not investigate in detail, it seems that it can not cope even with CLDRLocaleProviderAdapter.
The parser generated by DateTimeFormatter.ofPattern exhibits the following interesting behaviour which is preventing me from writing a pattern to parse a string like 20150100:
System.out.println(DateTimeFormatter.ofPattern("yyyyMM").parse("201501", YearMonth::from)); // works
System.out.println(DateTimeFormatter.ofPattern("yyyyMM'aa'").parse("201501aa", YearMonth::from)); // works
System.out.println(DateTimeFormatter.ofPattern("yyyyMM'00'").parse("20150100", YearMonth::from));
// java.time.format.DateTimeParseException: Text '20150100' could not be parsed at index 0
I debuged the code, it seems the problem is caused by the year field parsing beyond the end of the string (max width for three y's and more is always 19). However, I don't understand how it could work for the pattern without the '00' literal at the end.
Is there any way to fix this withing having to use a formatter builder?
Edit:
Since Jarrod below confirmed it's buggy, I did more googling and finally found the bug reports:
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8031085
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8032491
Both are only fixed in Java 9 though......
There is a bug in the DateTimePrinterParser:
I step debugged all the way through it, apparently you can not have digits as literals. Similar test codes proves this if you step debug all the way through to the DateTimeFormatterBuilder.parse() method you can see what it is doing wrong.
Apparently the Value(YearOfEra,4,19,EXCEEDS_PAD) parser consumes the 00 where they stop if those are not digits because it is looking for a number 4 to 19 digits long. The DateTimeFormatter that is embedded in the DateTimeParseContext is wrong.
If you put a non-digit character literal like xx it works, digit literals don't.
Both of these fail:
final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM'00'");
System.out.println(sdf.parse("20150100"));
Exception in thread "main" java.text.ParseException: Unparseable date:
"20150100" at java.text.DateFormat.parse(DateFormat.java:366)
final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMM'00'");
System.out.println(dateTimeFormatter.parse("20150100", YearMonth::from));
Exception in thread "main" java.time.format.DateTimeParseException:
Text '20150100' could not be parsed at index 0 at
java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
at
java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
Both of these succeed:
final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM'xx'");
System.out.println(sdf.parse("201501xx"));
Thu Jan 01 00:00:00 EST 2015
final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMM'xx'");
System.out.println(dateTimeFormatter.parse("201501xx", YearMonth::from));
2015-01
If you don't mind to use a 3rd-party-library then you might try my library Time4J whose newest version v4.18 can do what you wish:
import net.time4j.Month;
import net.time4j.range.CalendarMonth;
import net.time4j.format.expert.ChronoFormatter;
import net.time4j.format.expert.PatternType;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.text.ParseException;
import java.util.Locale;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
#RunWith(JUnit4.class)
public class CalendarMonthTest {
#Test
public void parse2() throws ParseException {
assertThat(
ChronoFormatter.ofPattern(
"yyyyMM'00'",
PatternType.CLDR,
Locale.ROOT,
CalendarMonth.chronology()
).parse("20150100"),
is(CalendarMonth.of(2015, Month.JANUARY)));
}
}
By the way, the links to the JDK-bug-log are not really related to your problem. Those issues only describe problems when applying adjacent digit parsing in context of fractional seconds. While that problem will be fixed with Java-9, your problem will not. Maybe you wish to open a new issue there? But I doubt that Oracle will treat it as bug. It is rather a new feature not supported until now by any library distributed by Oracle. Literals with (leading) digits are not expected in JSR-310 (aka java.time-package) to take part into adjacent-value-parsing (and in SimpleDateFormat also not).
Side note: Time4J is not just an answer to this detail (digit literals) but generally offers better performance in parsing and can be used in parallel with JSR-310 due to a lot of conversion methods. For example: To achieve an instance of YearMonth, just call calendarMonth.toTemporalAccessor() on the parsed result.
As an addendum to user177800's answer, you can use this form instead:
var formatter = new DateTimeFormatterBuilder()
.appendValue(ChronoField.YEAR, 4)
.appendValue(ChronoField.MONTH_OF_YEAR, 2)
.appendLiteral("00")
.toFormatter();
YearMonth.parse("20220200", formatter);
All part of java.time.
This question already has answers here:
Java 8 LocalDateTime is parsing invalid date
(5 answers)
Closed 6 years ago.
Either I don't quite grasp what the resolver style in java.time does, or there is a bug.
I have the following code (in Scala):
import java.sql.Timestamp
import java.time.format.{DateTimeFormatter, ResolverStyle}
import java.time.ZonedDateTime
val str = "2016-07-11T05:45:44.552+04:00"
val iso1 = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX")
val iso2 = iso1.withResolverStyle(ResolverStyle.STRICT)
Timestamp.from(ZonedDateTime.parse(str, iso1).toInstant) // works fine
Timestamp.from(ZonedDateTime.parse(str, iso2).toInstant) // nope!
The first version works and the second throws the following exception a java.time.format.DateTimeParseException. What I don't understand is why. The date and time are in my opinion valid.
See: https://docs.oracle.com/javase/8/docs/api/java/time/format/ResolverStyle.html#STRICT
This is incorrect ISO format, just use DateTimeFormatter.ISO_DATE_TIME.
I've been stuck on this particular problem for about a week now, and I figure I'm going to write this up as a question on here to clear out my thoughts and get some guidance.
So I have this case class that has a java.sql.Timestamp field:
case class Request(id: Option[Int], requestDate: Timestamp)
and I want to convert this to a JsObject
val q = Query(Requests).list // This is Slick, a database access lib for Scala
printList(q)
Ok(Json.toJson(q)) // and this is where I run into trouble
"No Json deserializer found for type List[models.Request]. Try to implement an implicit Writes or Format for this type." Okay, that makes sense.
So following the Play documentation here, I attempt to write a Format...
implicit val requestFormat = Json.format[Request] // need Timestamp deserializer
implicit val timestampFormat = (
(__ \ "time").format[Long] // error 1
)(Timestamp.apply, unlift(Timestamp.unapply)) // error 2
Error 1
Description Resource Path Location Type overloaded method value format with alternatives:
(w: play.api.libs.json.Writes[Long])(implicit r: play.api.libs.json.Reads[Long])play.api.libs.json.OFormat[Long]
<and>
(r: play.api.libs.json.Reads[Long])(implicit w: play.api.libs.json.Writes[Long])play.api.libs.json.OFormat[Long]
<and>
(implicit f: play.api.libs.json.Format[Long])play.api.libs.json.OFormat[Long]
cannot be applied to (<error>, <error>)
Apparently importing like so (see the documentation "ctrl+F import") is getting me into trouble:
import play.api.libs.json._ // so I change this to import only Format and fine
import play.api.libs.functional.syntax._
import play.api.libs.json.Json
import play.api.libs.json.Json._
Now that the overloading error went away, I reach more trubbles: not found: value __ I imported .../functional.syntax._ already just like it says in the documentation! This guy ran into the same issue but the import fixed it for him! So why?! I thought this might just be Eclipse's problem and tried to play run anyway ... nothing changed. Fine. The compiler is always right.
Imported play.api.lib.json.JsPath, changed __ to JsPath, and wallah:
Error 2
value apply is not a member of object java.sql.Timestamp
value unapply is not a member of object java.sql.Timestamp
I also try changing tacks and writing a Write for this instead of Format, without the fancy new combinator (__) feature by following the original blog post the official docs are based on/copy-pasted from:
// I change the imports above to use Writes instead of Format
implicit val timestampFormat = new Writes[Timestamp]( // ERROR 3
def writes(t: Timestamp): JsValue = { // ERROR 4 def is underlined
Json.obj(
/* Returns the number of milliseconds since
January 1, 1970, 00:00:00 GMT represented by this Timestamp object. */
"time" -> t.getTime()
)
}
)
ERROR 3: trait Writes is abstract, cannot be instantiated
ERROR 4: illegal start of simple expression
At this point I'm about at my wits' end here, so I'm just going back to the rest of my mental stack and report from my first piece of code
My utter gratefulness to anybody who can put me out of my coding misery
It's not necessarily apply or unapply functions you need. It's a) a function that constructs whatever the type you need given some parameters, and b) a function that turns an instance of that type into a tuple of values (usually matching the input parameters.)
The apply and unapply functions you get for free with a Scala case class just happen to do this, so it's convenient to use them. But you can always write your own.
Normally you could do this with anonymous functions like so:
import java.sql.Timestamp
import play.api.libs.functional.syntax._
import play.api.libs.json._
implicit val timestampFormat: Format[Timestamp] = (
(__ \ "time").format[Long]
)((long: Long) => new Timestamp(long), (ts: Timestamp) => (ts.getTime))
However! In this case you fall foul of a limitation with the API that prevents you from writing formats like this, with only one value. This limitation is explained here, as per this answer.
For you, a way that works would be this more complex-looking hack:
import java.sql.Timestamp
import play.api.libs.functional.syntax._
import play.api.libs.json._
implicit val rds: Reads[Timestamp] = (__ \ "time").read[Long].map{ long => new Timestamp(long) }
implicit val wrs: Writes[Timestamp] = (__ \ "time").write[Long].contramap{ (a: Timestamp) => a.getTime }
implicit val fmt: Format[Timestamp] = Format(rds, wrs)
// Test it...
val testTime = Json.obj("time" -> 123456789)
assert(testTime.as[Timestamp] == new Timestamp(123456789))