Why is it that Dart's DateTime.parse rolls to january next year when trying to parse the "13" month? - flutter

When working on a Flutter/Dart project where I had to parse different methods entering dates into a form, I found that if the user wrote i.e (by accident) '09.13' for december 9th (wrote 13 instead of 12), the parse result for parse rolled over to january next year.
Given in code:
DateFormat format = 'dd.MM';
try{
var dateTime = format.parse('09.13');
print("dateTime = ${dateTime.toString()}");
}on FormatException{
print("dateTime error");
}
I expected this to be
dateTime error
but instead I got
dateTime = 1971-01-09 00:00:00.000
I understand the reset to 1970, since I didn't give any year, I'd rather expect it to give a FormatException to show the user that there is a flaw in the entered date... ...but rolling over to the next year (1971) and give no Exception ?
Is there any reason for this behavior, or do I simply need to fight with RegEx for this dateTime check...

this is actually, not something to fix, the DateFormat algorithm was made to calculate the expected DateTime from the input:
9 days and 13 months logically equal 1 year, 1 month, and 9 days.
However, using dart you can throw your own custom FormatException, as example you could do something like this:
try{
String stringDate = "09.13";
if(checkMonthLimit(stringDate)) {
var dateTime = format.parse(stringDate);
print("dateTime = ${dateTime.toString()}");
} else {
throw FormatException("some text here");
}
}on FormatException{
print("dateTime error");
}
bool checkMonthLimit(String txt) {
return int.parse(txt.split(".")[1]) <= 12;
}
Now if the month is above 12, the method will return false, so it enter the else block, then throws the FormatException, which will be catched in the catch block.

Related

Flutter DateTime error on string to DateTime [duplicate]

Say I have a string
"1974-03-20 00:00:00.000"
It is created using DateTime.now(),
how do I convert the string back to a DateTime object?
DateTime has a parse method
var parsedDate = DateTime.parse('1974-03-20 00:00:00.000');
https://api.dartlang.org/stable/dart-core/DateTime/parse.html
There seem to be a lot of questions about parsing timestamp strings into DateTime. I will try to give a more general answer so that future questions can be directed here.
Your timestamp is in an ISO format. Examples: 1999-04-23, 1999-04-23 13:45:56Z, 19990423T134556.789. In this case, you can use DateTime.parse or DateTime.tryParse. (See the DateTime.parse documentation for the precise set of allowed inputs.)
Your timestamp is in a standard HTTP format. Examples: Fri, 23 Apr 1999 13:45:56 GMT, Friday, 23-Apr-99 13:45:56 GMT, Fri Apr 23 13:45:56 1999. In this case, you can use dart:io's HttpDate.parse function.
Your timestamp is in some local format. Examples: 23/4/1999, 4/23/99, April 23, 1999. You can use package:intl's DateFormat class and provide a pattern specifying how to parse the string:
import 'package:intl/intl.dart';
...
var dmyString = '23/4/1999';
var dateTime1 = DateFormat('d/M/y').parse(dmyString);
var mdyString = '04/23/99';
var dateTime2 = DateFormat('MM/dd/yy').parse(mdyString);
var mdyFullString = 'April 23, 1999';
var dateTime3 = DateFormat('MMMM d, y', 'en_US').parse(mdyFullString));
See the DateFormat documentation for more information about the pattern syntax.
DateFormat limitations:
DateFormat cannot parse dates that lack explicit field separators. For such cases, you can resort to using regular expressions (see below).
Prior to version 0.17.0 of package:intl, yy did not follow the -80/+20 rule that the documentation describes for inferring the century, so if you use a 2-digit year, you might need to adjust the century afterward.
As of writing, DateFormat does not support time zones. If you need to deal with time zones, you will need to handle them separately.
Last resort: If your timestamps are in a fixed, known, numeric format, you always can use regular expressions to parse them manually:
var dmyString = '23/4/1999';
var re = RegExp(
r'^'
r'(?<day>[0-9]{1,2})'
r'/'
r'(?<month>[0-9]{1,2})'
r'/'
r'(?<year>[0-9]{4,})'
r'$',
);
var match = re.firstMatch(dmyString);
if (match == null) {
throw FormatException('Unrecognized date format');
}
var dateTime4 = DateTime(
int.parse(match.namedGroup('year')!),
int.parse(match.namedGroup('month')!),
int.parse(match.namedGroup('day')!),
);
See https://stackoverflow.com/a/63402975/ for another example.
(I mention using regular expressions for completeness. There are many more points for failure with this approach, so I do not recommend it unless there's no other choice. DateFormat usually should be sufficient.)
import 'package:intl/intl.dart';
DateTime brazilianDate = new DateFormat("dd/MM/yyyy").parse("11/11/2011");
you can just use : DateTime.parse("your date string");
for any extra formating, you can use "Intl" package.
void main() {
var dateValid = "30/08/2020";
print(convertDateTimePtBR(dateValid));
}
DateTime convertDateTimePtBR(String validade)
{
DateTime parsedDate = DateTime.parse('0001-11-30 00:00:00.000');
List<String> validadeSplit = validade.split('/');
if(validadeSplit.length > 1)
{
String day = validadeSplit[0].toString();
String month = validadeSplit[1].toString();
String year = validadeSplit[2].toString();
parsedDate = DateTime.parse('$year-$month-$day 00:00:00.000');
}
return parsedDate;
}
a string can be parsed to DateTime object using Dart default function DateTime.parse("string");
final parsedDate = DateTime.parse("1974-03-20 00:00:00.000");
Example on Dart Pad
String dateFormatter(date) {
date = date.split('-');
DateFormat dateFormat = DateFormat("yMMMd");
String format = dateFormat.format(DateTime(int.parse(date[0]), int.parse(date[1]), int.parse(date[2])));
return format;
}
I solved this by creating, on the C# server side, this attribute:
using Newtonsoft.Json.Converters;
public class DartDateTimeConverter : IsoDateTimeConverter
{
public DartDateTimeConverter()
{
DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFK";
}
}
and I use it like this:
[JsonConverter(converterType: typeof(DartDateTimeConverter))]
public DateTimeOffset CreatedOn { get; set; }
Internally, the precision is stored, but the Dart app consuming it gets an ISO8601 format with the right precision.
HTH

How to change "2022-05-13T17:02:34Z" string to a millisecondsSinceEpoch in flutter [duplicate]

Say I have a string
"1974-03-20 00:00:00.000"
It is created using DateTime.now(),
how do I convert the string back to a DateTime object?
DateTime has a parse method
var parsedDate = DateTime.parse('1974-03-20 00:00:00.000');
https://api.dartlang.org/stable/dart-core/DateTime/parse.html
There seem to be a lot of questions about parsing timestamp strings into DateTime. I will try to give a more general answer so that future questions can be directed here.
Your timestamp is in an ISO format. Examples: 1999-04-23, 1999-04-23 13:45:56Z, 19990423T134556.789. In this case, you can use DateTime.parse or DateTime.tryParse. (See the DateTime.parse documentation for the precise set of allowed inputs.)
Your timestamp is in a standard HTTP format. Examples: Fri, 23 Apr 1999 13:45:56 GMT, Friday, 23-Apr-99 13:45:56 GMT, Fri Apr 23 13:45:56 1999. In this case, you can use dart:io's HttpDate.parse function.
Your timestamp is in some local format. Examples: 23/4/1999, 4/23/99, April 23, 1999. You can use package:intl's DateFormat class and provide a pattern specifying how to parse the string:
import 'package:intl/intl.dart';
...
var dmyString = '23/4/1999';
var dateTime1 = DateFormat('d/M/y').parse(dmyString);
var mdyString = '04/23/99';
var dateTime2 = DateFormat('MM/dd/yy').parse(mdyString);
var mdyFullString = 'April 23, 1999';
var dateTime3 = DateFormat('MMMM d, y', 'en_US').parse(mdyFullString));
See the DateFormat documentation for more information about the pattern syntax.
DateFormat limitations:
DateFormat cannot parse dates that lack explicit field separators. For such cases, you can resort to using regular expressions (see below).
Prior to version 0.17.0 of package:intl, yy did not follow the -80/+20 rule that the documentation describes for inferring the century, so if you use a 2-digit year, you might need to adjust the century afterward.
As of writing, DateFormat does not support time zones. If you need to deal with time zones, you will need to handle them separately.
Last resort: If your timestamps are in a fixed, known, numeric format, you always can use regular expressions to parse them manually:
var dmyString = '23/4/1999';
var re = RegExp(
r'^'
r'(?<day>[0-9]{1,2})'
r'/'
r'(?<month>[0-9]{1,2})'
r'/'
r'(?<year>[0-9]{4,})'
r'$',
);
var match = re.firstMatch(dmyString);
if (match == null) {
throw FormatException('Unrecognized date format');
}
var dateTime4 = DateTime(
int.parse(match.namedGroup('year')!),
int.parse(match.namedGroup('month')!),
int.parse(match.namedGroup('day')!),
);
See https://stackoverflow.com/a/63402975/ for another example.
(I mention using regular expressions for completeness. There are many more points for failure with this approach, so I do not recommend it unless there's no other choice. DateFormat usually should be sufficient.)
import 'package:intl/intl.dart';
DateTime brazilianDate = new DateFormat("dd/MM/yyyy").parse("11/11/2011");
you can just use : DateTime.parse("your date string");
for any extra formating, you can use "Intl" package.
void main() {
var dateValid = "30/08/2020";
print(convertDateTimePtBR(dateValid));
}
DateTime convertDateTimePtBR(String validade)
{
DateTime parsedDate = DateTime.parse('0001-11-30 00:00:00.000');
List<String> validadeSplit = validade.split('/');
if(validadeSplit.length > 1)
{
String day = validadeSplit[0].toString();
String month = validadeSplit[1].toString();
String year = validadeSplit[2].toString();
parsedDate = DateTime.parse('$year-$month-$day 00:00:00.000');
}
return parsedDate;
}
a string can be parsed to DateTime object using Dart default function DateTime.parse("string");
final parsedDate = DateTime.parse("1974-03-20 00:00:00.000");
Example on Dart Pad
String dateFormatter(date) {
date = date.split('-');
DateFormat dateFormat = DateFormat("yMMMd");
String format = dateFormat.format(DateTime(int.parse(date[0]), int.parse(date[1]), int.parse(date[2])));
return format;
}
I solved this by creating, on the C# server side, this attribute:
using Newtonsoft.Json.Converters;
public class DartDateTimeConverter : IsoDateTimeConverter
{
public DartDateTimeConverter()
{
DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFK";
}
}
and I use it like this:
[JsonConverter(converterType: typeof(DartDateTimeConverter))]
public DateTimeOffset CreatedOn { get; set; }
Internally, the precision is stored, but the Dart app consuming it gets an ISO8601 format with the right precision.
HTH

Using Primeng Datepicker how do I only enable the last day of months?

So my question is pretty simple. I'd like to have specific dates that are enabled on a datepicker, like only the last day of any month, for example 30/06/2019, 31/07/2019
Primng Datepicker
<p-calendar formControlName="date"></p-calendar>
It is a simple hack for your requirement.
In your component.html use min and max date and (onMonthChange) method to update min and max value of date when user changes the month. Trick is just make min and max date equal to last day of the month.
<p-calendar [(ngModel)]="value" tabindex="0" [maxDate]="maxDateValue"
[minDate]="minDateValue" readonlyInput="true"
(onMonthChange)="onMonthChange($event)">
</p-calendar>
And in component.ts file use below code:
public maxDateValue: Date;
public minDateValue: Date;
ngOnInit() {
this.setMinMaxDate();
}
setMinMaxDate() {
var nowdate = new Date();
this.maxDateValue = new Date(nowdate.getFullYear(), nowdate.getMonth() + 1, 0);
this.minDateValue = new Date(nowdate.getFullYear(), nowdate.getMonth() + 1, 0);
}
// method to handle month change.
onMonthChange(e:any) {
this.minDateValue = new Date(e.year, e.month, 0);
this.maxDateValue = new Date(e.year, e.month, 0);
}
You must be thinking why at time of initialization I am using nowdate.getMonth() + 1, but inside onMonthChange only e.month, not adding + 1.
You need to go through this find last and first date of month article how to get the last and first date of a month and print the values of month in console and see the differences. Then you will understand easily.
If you just need one day of each month you should use the month view
<p-calendar [(ngModel)]="dateValue"
view="month" dateFormat="mm/yy"
[yearNavigator]="true"
yearRange="2000:2030"></p-calendar>

Validating two dates in acrobat javascripts

well the code I posted below all works perfectly except for a small detail. When I input today date in the field dateEntered, the later rejects it, it validates if the date entered is before todays date, validate if the date falls on a weekends, but it also show an error message when it is todays date. Actually the user should be able to enter Today or after date.
Anyone can tell me where am wrong, already tried every possible ways but still not working even the ( ==) or (===) or (<=) ..nothing
if (event.value!="")
{
var e = util.scand("ddd, dd.mmm.yy", event.value);
var a = (e.getTime()) < (new Date().getTime());
if (a) {
app.alert("The Date cannot be before Today's Date", 1);
event.rc = null;
}
if (e.getDay()==6 || e.getDay()==0) {
app.alert("Cannot take permission on a Weekend!", 2);
event.rc=null;
}
}
I found the solution to my problem, I had to set the hour to 0. Thank to the one who updated this on stackoverflow and sorry forget to retain your name.
if (event.value!="")
{
var e = util.scand("ddd, dd.mmm.yy", event.value);
var b=new Date();
b.setHours(0,0,0,0);
if (e<b) {
app.alert("ERROR: Date cannot be before"+" "+ new Date(b), 5);
event.rc = null;
}
if (e.getDay()==6 || e.getDay()==0) {
app.alert("ALERT: The date you entered ("+event.value+") falls on a WEEKEND!", 3);
event.rc=null;
}
}
This codes also contains a condition of removing one weekend from the dates since the number of leaves allowed to take ranges from 1 to 7 thus only one weekend is remove.

Converting Date to other format in C#

Can any one suggest me the following:
i> how to convert 3/12/2010 10:15 to the format Mar 12, 2010 10:15 in c#.
ii> how to remove time part out of it(i.e after the conversion i want Mar 12, 2010
Thanks in advance.
nimesh,
The String.Format function should be able to accommodate your needs (updated to reflect my comment):
string inputString = "03/12/2012";
DateTime dt = DateTime.MinValue;
try {
dt = DateTime.Parse(inputString);
}
catch (Exception ex) {
// handle the exception however you like.
return;
}
string formattedDate = String.Format("{0:MMM d, yyyy}", dt);
To avoid the above, check out TryParse:
http://msdn.microsoft.com/en-us/library/system.datetime.tryparse.aspx
You can format it in lots of ways:
http://www.csharp-examples.net/string-format-datetime/
Use DateTime.Parse(...) to parse the input string into a DateTime object, and then use Format to make the string as posted by mikey.