Let's say that I have following parser inside my get method:
from flask.ext.restful import reqparse
parser = reqparse.RequestParser()
parser.add_argument('when', type=datetime, help='Input wasn\'t valid!')
And then I want to test the said get method with curl...
curl --data "when=[WHAT SHOULD I WRITE HERE?]" localhost:5000/myGet
So the question is, how I should call the get method? I've tried numerous different formats, tried to read rfc228 standard, etc. but I can't figure out the right format.
Kinda late, but I've just been in the same problem, trying to parse a datetime with RequestParser, and sadly the docs are not so helpful for this scenario, so after seeing and testing RequestParser and Argument code, I think I found the problem:
When you use type=datetime in the add_argument method, under the hood it just calls datetime with the arg, like this: datetime(arg), so if your param is a string like this: 2016-07-12T23:13:3, the error will be an integer is required.
In my case, I wanted to parse a string with this format %Y-%m-%dT%H:%M:%S into a datetime object, so I thought to use something like type=datetime.strptime but as you know this method needs a format parameter, so I finally used this workaround:
parser.add_argument('date', type=lambda x: datetime.strptime(x,'%Y-%m-%dT%H:%M:%S'))
As you can see in this way you can use whatever format datetime you want. Also you can use partial functool instead of lambda to get the same result or a named function.
This workaround is in the docs.
Just an update on Flask-Restful (0.3.5): it is possible to use the own library date and datetime functionality parsing, if ISO 8601 or RFC 822 suffices:
from flask_restful import inputs
parser.add_argument('date', type=inputs.datetime_from_iso8601)
So the request would be,
curl --data "date=2012-01-01T23:30:00+02:00" localhost:5000/myGet
From the docs
Related
I have a time string, which looks like this: 20170822T194135+00. This is called basic ISO:8601 format, if I understood correctly.
When I try to parse it using ZonedDateTime, it throws exception, complaining that it can't parse it.
SO, how do I convert this string to a valid Joda datetime object?
Do I need to build manual "format" to parse it (this would be silly, considering it's a standard format)?
Desperately, I've actually tried to implement custom format:
const time = ZonedDateTime.parse(timeString, DateTimeFormatter.ofPattern(`yyyyMMdd'T'HHmmssZ`));
But, it throws error on column 15. Looks like it fails to parse the timezone. Is my implementation correct? How do I make it work?
I could do it using the pattern x as described in the docs (this pattern accepts offsets like +00).
Then I parsed directly to a ZonedDateTime:
const formatter = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmssx");
const time = ZonedDateTime.parse("20170822T194135+00", formatter);
The resulting time variable has the value equivalent to 2017-08-22T19:41:35Z.
The built-in formatters (such as ISO_LOCAL_DATE_TIME) can't parse this format, so the only way seems to be creating a formatter.
I have been looking at the above question and have most of it correct.
I am going to get a datetime in Zulu, and then will want to output that format.
My first go is just as simple as:
DateFormat format = new DateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
My issue I am having is the T and Z. Obviously T is used to separate the date from the time and the Z is representative of Zulu time.
That being said the users will be entering a datetime in Zulu, so it wont need to be converted from Local to Zulu, so i was not sure if 'Z' is an acceptable result. I was not sure if there is a different want to handle this, or if my result was the best answer.
Try this package, Jiffy.
String isoFomart = Jiffy().format(); // This will return ISO format from now
You can also add your DateTime object
String isoFomart = Jiffy(DateTime.now()).format(); // This will also return ISO format from now
Hope this helped
The DateTime object has a method called: toIso8601String which is used to return an ISO formatted string. The 'Z' will be added if isUTC is true, otherwise the result will not have the Z in it.
Make sure that the DateTime object itself is correctly set to UTC as if you look in the constructor for the class will tell you a lot of the defaults are local with the exception of the DateTime.utc() static function.
In that concept, you dont really need a DateFormat use to define an iso string.
I am trying to get this pattern 'dd-MM-yyyy' with a variable of type DateTime
#{DateTimeFormat.forPattern("dd-MM-YYYY").parseDateTime(user.birthday.toString)}
But I am getting this error
java.lang.IllegalArgumentException: Invalid format: "2015-12-10T00:00:00.000Z" is malformed at "15-12-10T00:00:00.000Z"
Is there a way to do this with nscala-time?
makes a difference if I am using UTC?
UPDATE
For the moment I am casting to Date and doing this
#{Dates.format(user.birthday.toDate, "dd-MM-YYYY")}
But maybe is a better way without casting
thank you
So, if I understood your question correctly, you are trying to achieve the following:
Parse date from a string using a date format
Print/Display the date in another format.
Try the below:
#{Dates.format(DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ").parseDateTime(user.birthday.toString), "dd-MM-YYYY")}
I'm working on an app that allows the user to edit several dates in a form. The dates are rendered in the European format (DD-MM-YYYY) while the databases uses the default YYYY-MM-DD format.
There are several ways to encode/decode this data back and forth from the database to the user, but they all require a lot of code:
Use a helper function to convert the date before saving and after retrieving (very cumbersome, requires much code)
Create a separate attribute for each date attribute, and use the setNameAttribute and getNameAttribute methods to decode/encode (also cumbersome and ugly, requires extra translations/rules for each attribute)
Use JavaScript to convert the dates when loading and submitting the form (not very reliable)
So what's the most efficient way to store, retrieve and validate dates and times from the user?
At some point, you have to convert the date from the view format to the database format. As you mentioned, there are a number of places to do this, basically choosing between the back-end or the front-end.
I do the conversion at the client side (front-end) using javascript (you can use http://momentjs.com to help with this). The reason is that you may need different formats depending on the locale the client is using (set in the browser or in his profile preferences for example). Doing the format conversion in the front-end allows you to convert to these different date formats easily.
Another advantage is that you can then use the protected $dates property in your model to have Laravel handle (get and set) these dates automatically as a Carbon object, without the need for you to do this (see https://github.com/laravel/framework/blob/master/src/Illuminate/Database/Eloquent/Model.php#L126).
As for validation, you need can then use Laravel's built-in validation rules for dates, like this:
'date' => 'required|date|date_format:Y-n-j'
While client-side is good for UX, it doesn't let you be sure, all will be good.
At some point you will need server-side validation/convertion anyway.
But here's the thing, it's as easy as this:
// after making sure it's valid date in your format
// $dateInput = '21-02-2014'
$dateLocale = DateTime::createFromFormat('d-m-Y', $dateInput);
// or providing users timezone
$dateLocale =
DateTime::createFromFormat('d-m-Y', $dateInput, new DateTime('Europe/London'));
$dateToSave = $dateLocale
// ->setTimeZone(new TimeZone('UTC')) if necessary
->format('Y-m-d');
et voila!
Obviously, you can use brilliant Carbon to make it even easier:
$dateToSave = Carbon::createFromFormat('d-m-Y', $dateInput, 'Europe/London')
->tz('UTC')
->toDateString(); // '2014-02-21'
Validation
You say that Carbon throws exception if provided with wrong input. Of course, but here's what you need to validate the date:
'regex:/\d{1,2}-\d{1,2}-\d{4}/|date_format:d-m-Y'
// accepts 1-2-2014, 01-02-2014
// doesn't accept 01-02-14
This regex part is necessary, if you wish to make sure year part is 4digit, since PHP would consider date 01-02-14 valid, despite using Y format character (making year = 0014).
The best way I found is overriding the fromDateTime from Eloquent.
class ExtendedEloquent extends Eloquent {
public function fromDateTime($value)
{
// If the value is in simple day, month, year format, we will format it using that setup.
// To keep using Eloquent's original fromDateTime method, we'll convert the date to timestamp,
// because Eloquent already handle timestamp.
if (preg_match('/^(\d{2})\/(\d{2})\/(\d{4})$/', $value)) {
$value = Carbon\Carbon::createFromFormat('d/m/Y', $value)
->startOfDay()
->getTimestamp();
}
return parent::fromDateTime($value);
}
}
I'm new in PHP, so I don't know if it's the best approach.
Hope it helps.
Edit:
Of course, remember to set all your dates properties in dates inside your model. eg:
protected $dates = array('IssueDate', 'SomeDate');
I am in the unfortunate position that I need to use a composite id in a Grails app where I work with legacy data. This means I have to override some actions in the controller, but as I did this I was struck by the fact that I could not use use a date argument directly as a parameter to a dynamic method.
Instead of just doing MyLegacyObj.findBySystemIdAndLogDate(params.systemId, params.logDate), I first needed to parse the date string before giving it to the dynamic method. To further complicate matters I had no idea what format the date string had (until I added lots of log.debug() string to the output). So now I have a bit of code looking like this
def formatter = new SimpleDateFormat("EEE MMM d HH:mm:ss z yyyy")
MyLegacyObj.findBySystemIdAndLogDate(params.systemId, formatter.parse(params.logDate));
This feels unoptimal, no to say dangerous (what if the date format changes with the locale?)? What would be a recommended way of doing this, and do I really need to parse dates at all?
Date is a pretty complex object and params are just Strings, so Date is submitted in parts. It is "magically" assembled from the parts when assigning x.properties = params.
Command object will do the work for you, if you add a Date field to it.
It has nothing to do with methods' dynamic or static invocation. Your GSP that renders Date editor might interfere too.