Writing Android app to interact with already existing .Net API and ran into date serialization problem. I know that .Net Json date format is /Date(timestamp-timezone)/, however even if I format it like this, I still get error: 'There was an error deserializing the object of type ShoutsOut.Entities.MobileUser. DateTime content '\/Date(1469457720840-0000)\/' does not start with '\/Date(' and end with ')\/' as required for JSON.'
Full stack trace:
at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject(XmlDictionaryReader reader, Boolean verifyObjectName)
at System.ServiceModel.Dispatcher.SingleBodyParameterDataContractMessageFormatter.ReadObject(Message message)
at System.ServiceModel.Dispatcher.SingleBodyParameterMessageFormatter.DeserializeRequest(Message message, Object[] parameters)
at System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(Message message, Object[] parameters)
at System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message message, Object[] parameters)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc) at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
I'm formatting it like this:
public static String toJson(Date date) {
return "\\/Date(" + date.getTime() + "-0000)\\/";
}
Tried to:
Remove timezone
Remove / /
add ' between the date
Found slightly different format "\"\\/Date("+date.getTime+"-0500)\\/\"", didn't work either
This answer solved it for me, basically had to change date data type to DateTime from Joda time library, and implemented custom serializer/deserializer
Related
We have api: call_summary/
{
"id": 2,
"number: "xyz",
"call_time": "2021-10-11T03:50:23Z"
}
We have multiple users with various timezones like ADT, EDT, IST, etc. When users access this API the call_time should change according to user timezone. I tried to use #JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "IST"), but this won't allow us to change the call_time dynamically.
Is there any way to do it using annotations or filters?
I would recommend storing call_time in two columns, UTC and users local time-zone.
By doing so, it will eliminate complexity and confusion at both ends (server and client)
Check the following link, it may help you: Pass browser timezone to the backend springboot application to generate reports with dates as per the browser timezone. According to the latter, you can use TimeZone as input to your controller. You could do something like the following:
#RestController
public class TestController {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
#GetMapping(value = "/test")
public String generate(TimeZone timezone) throws IOException {
return LocalDateTime.now().atZone(timezone.toZoneId()).format(formatter);
}
}
Alternatively, you could get the timezone from HttpServletRequest.
JSON Serialize is the best fit for this custom data conversion as per user or user role. I created the converter class and called by #JsonSerialize(converter = LocalDateTimeToStringConverter.class) and #JsonDeserialize(converter = StringToLocalDatetimeConverter.class). It worked as per my expection.
For reference, I attached the sample link below.
Custom conversion using JSON-Serialize-Deserialize
I have a request body have date field and I want to validate the input of the date and return error code 400 BadRequest if the format is wrong.
If I use the JsonFormat then it throws error 500:
#JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd")
private Date dateAt;
So I changed the field to String and then parse and throw BadRequest format everywhere using the getDate()
I am not really satisfied with this approach. Is there any other elegant way to achieve this validation?
I think I will accept error 500 from JSON formatter and skip my custom exception.
Since Java 8, you should avoid using Date. Java 8 brought an entirely new date and time API.
According to your question, a suitable replacement for Date would be LocalDate, which is expected to be in the format yyyy-MM-dd.
Jackson has a module supporting the new date and time API and an exception will be thrown if the date is not in the correct format. When serializing, you want to make sure the WRITE_DATES_AS_TIMESTAMPS feature is disabled, so the values will be written according to the ISO 8601 format.
I have dates in XML
<date>1980-03-07+03:00</date>
I use this data in my tests and i get it from XML, but in the web page it is displayed in dd.MM.yyyy form, so i have to convert it to that format. I have following method for this:
public String convertXMLDateToString(String xmlDate) throws ParseException, DatatypeConfigurationException {
return new SimpleDateFormat("dd.MM.yyyy").format(new Date(DatatypeConverter.parseDate(xmlDate).getTimeInMillis())) ;
}
but this is returning 06.03.1980 . It is probably a timezone issue - how to i get the right date? The reason for using strings is that these are webdriver tests that i am writing.
Its returning actually the correct date. Either your test data is corrupted or you have a bug in your application. However if you're sure, that there's no bug and test data isn't corrupted, you can set the correct time zone manually, by doing something like this:
Calendar calendar = DatatypeConverter.parseDate(xmlDate);
calendar.setTimeZone(TimeZone.getDefault());
return new SimpleDateFormat("dd.MM.yyyy").format(new Date(calendar.getTimeInMillis()));
I'm trying to retrieve a list of events from a google calendar, using the Java api (jar version v3-rev9-1.7.0-beta)
This code works fine
Events e = service.events().list("primary").
setMaxResults(3).
execute();
where service is a Calendar object.
However, if I add a setTimeMin or setTimeMax parameter, like this
Date now = new java.util.Date();
Events e = service.events().list("primary").
setTimeMin(new DateTime(now)).
setMaxResults(3).
execute();
it returns a failure message, "Bad Request".
(note that as of this version, the setTime functions take a google DateTime object. I've also tried with the previous version of the jar, which takes a string, but received the same message).
So I was just wondering if anyone has successfully used these functions - perhaps they're not supposed to be called in this manner? Is there a way to get more detail back on the error?
Thanks :)
DateTime startTime = new DateTime(new Date(), TimeZone.getDefault());
Sorts the problem
I also encountered this. It seems the format of the DateTime.toString() or DateTime.toStringRfc3339() methods are incorrect as input to setTimeMin().
The DateTime.toString() format is:
2012-07-04T21:02:16.590
yyyy-MM-dd'T'HH:mm:ss.SSS (SimpleDateFormat notation)
The format which it expects seems to be close to xsd:datetime format (whatever that is):
2012-07-04T21:02:16Z (zulu, gmt)
2012-07-04T21:02:16-07:00 (mst, -7h)
2012-07-04T21:02:16-0700 (it also works without the colon in the timezone)
yyyy-MM-dd'T'HH:mm:ssZ (SimpleDateFormat)
Formatting can be done with a SimpleDateFormat:
SimpleDateFormat FMT_TIME=new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
String fromTimeStr=FMT_TIME.format(new Date());
Events evts = client.events().list(cal.getUid()).setTimeMin(fromTimeStr)
.execute();
Now, since I'm using the older API, I'm not sure how this would be done if the only method is setTimeMin(DateTime), but this should get you closer.
The Google documentation or source should mention this somewhere.
So I'm modifying one of the opensource Google I/O opensource applications (2010) and I'm getting the following error when trying to sync the app with using custom Google spreadsheet, same headings different data (appears to sync fine with the default Google spreadsheet)
"Sync error: Problem parsing timestamp: java.text.ParseException: Unparseable date: "null 2010 10:45am -0700"
This is the Java Code that's throwing the error
private static long parseTime(String date, String time) throws HandlerException {
final String composed = String.format("%s 2010 %s -0700", date, time);
try {
return sTimeFormat.parse(composed).getTime();
} catch (java.text.ParseException e) {
throw new HandlerException("Problem parsing timestamp", e);
}
}
Here's links to the information (Atom) which it is trying to parse:
My Data
https://spreadsheets.google.com/feeds/worksheets/0AmvmSNjQXtJFdE1lTlFxVXZCLUN0OFpqa3oyM2d4bEE/public/basic
Google Data
http://spreadsheets.google.com/feeds/worksheets/twd6syM493oFqIFWeIm8qGw/public/basic"
I can't figure out why I'm getting this error. Any help would be greatly appreciated.
Check the parameter date you pass into this method. It seems to be null, which obviously is not a valid date.
Because #henrik has already posted what your actual current problem is, I'm giving a few recommendations based on your posted code:
You're using sTimeFormat, which must be at least a static variable, and is probably final as well (and usually should be, in this context). However, you aren't following naming conventions -it should probably be named TIMESTAMP_FORMATTER (if the only thing you do is get an actual date, use TIMESTAMP_PARSER). Also, although you're not likely to be using multiple threads on an android device, please be aware DateFormat and SimpleDateFormat are NOT threadsafe - the standard practice is to contruct a copy for each use.
You're manually formatting the timestamp itself, before attempting to parse it. There's no point - you should be using the existing data (eiither from the xml directly, or the rendered html), and supplying a custom formatting string.
You're setting two parts of the dates, year and timezone. At minimum, that should be moved outside of the actual parse piece. You should probably write a setToCanonicalDate method or something that takes the output from your parsing and sets it to the valid year and timezone. And how far are you distributing that app? I live in the Pacific Timezone - your default won't do me any good.
This is how you can work with time and long:
Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_MONTH, dp.getDayOfMonth());
c.set(Calendar.MONTH, dp.getMonth());;
c.set(Calendar.YEAR, dp.getYear());
long l = c.getTime().getTime();