Discussions related to Visual Prolog
User avatar
George
Active Member
Posts: 47
Joined: 19 Sep 2011 8:54

Do we have any built in predicate to validate whether the input date is valid or not..??

Unread post by George »

Do we have any built in predicate to validate whether the input date is valid or not..??

ex: date format is CCYY/MM/DD(2012/06/28) - I want to check whether the input date is valid.. (If the input date is valid then my output will be "20120628")

predicate should fail if it's not a valid date (ex: 1. 2012/00/29 - month is not valid. 2. 2012/01/37 - date is not valid)

I did this using my own logic for year/month and date..

The following is the one i tried,

Code: Select all

class predicates         getFormattedValidDate : (string, string) determ  (i, o).         chkLeapYear : (unsigned) -> integer.         chkValidDayAndMonth : (string, string, integer) determ.         totDaysInMonth : (string, string) determ (i, o).         clauses         getFormattedValidDate("", ""):-                 !.         getFormattedValidDate(Date,NewDate):-                 fronttoken(Date,CCYY,_),                 4 = length(CCYY),                 MM = substring(Date,5,2),         DD = substring(Date,8,2),                 Out = chkLeapYear(toUnsigned(CCYY)),                 chkValidDayAndMonth(MM,DD,Out),         NewDate = format("%s%s%s",CCYY,MM,DD).                 %return 1 if it is the leap year.         %And return 0 if it is not the leap year         chkLeapYear(Year) = 1:-                 time_api::isLeapYear(Year),                 !.         chkLeapYear(_) = 0.       chkValidDayAndMonth("02","29",1) :- !.                               chkValidDayAndMonth(MM,DD,_) :-                                     totDaysInMonth(MM,Days),         DD <= Days.       totDaysInMonth("01","31"):- !.     totDaysInMonth("02","28"):- !.     totDaysInMonth("03","31"):- !.     totDaysInMonth("04","30"):- !.     totDaysInMonth("05","31"):- !.     totDaysInMonth("06","30"):- !.     totDaysInMonth("07","31"):- !.     totDaysInMonth("08","31"):- !.     totDaysInMonth("09","30"):- !.     totDaysInMonth("10","31"):- !.     totDaysInMonth("11","30"):- !.     totDaysInMonth("12","31").
I don't find any predicate which will check date is valid or month is valid or not..

Please advice.
Kind Regards,
George Ananth. S | Prolog Developer
georgeananth.prolog@gmail.com
+91 9791499282
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls »

(I think this has been discussed before).

Anyway, assuming that you can yourself split the string into the components and convert these to integers, the simplest way is to create a time object from the components, and then ask for the components of that time object. If they are the same the date is valid.

Code: Select all

class predicates     isValidDate : (integer Year, integer Month, integer Day) determ. clauses     isValidDate(Year, Month, Day) :-         time::newDate(Year, Month, Day):getDate(Y, M, D),         Y = Year,         M = Month,         D = Day.
Regards Thomas Linder Puls
PDC
User avatar
George
Active Member
Posts: 47
Joined: 19 Sep 2011 8:54

Unread post by George »

It's really nice approach :!:..

Thanks for your help... :D
Kind Regards,
George Ananth. S | Prolog Developer
georgeananth.prolog@gmail.com
+91 9791499282
User avatar
George
Active Member
Posts: 47
Joined: 19 Sep 2011 8:54

Unread post by George »

time::newDate(IYear, IMonth, IDay) predicate,
IYear = 2002
IMonth = 03
IDay = 10
The build-in predicate getDate/3 is not giving the expected result for the above scenarios,

The output of the getDate/3 predicate is following,
D = 9
M = 3
Y = 2002
since the date is given as 9 instead of 10. The date been considered as a not valid date..

Even though that was the valid date this predicate fails. Please let me know is there any bug with the built-in predicate getDate/3.

And one magical thing is that, this issue happened only when I used the 64 bit operating system.


Please help me to fix this issue.
Last edited by George on 14 Sep 2012 12:26, edited 1 time in total.
Kind Regards,
George Ananth. S | Prolog Developer
georgeananth.prolog@gmail.com
+91 9791499282
User avatar
George
Active Member
Posts: 47
Joined: 19 Sep 2011 8:54

Unread post by George »

I've modified the code in the following way..

Code: Select all

TimeObj = time::new(),                     TimeObj:setDate(IYear, IMonth, IDay),                     TimeObj:getDate(Y, M, D),                     Y = IYear,                     M = IMonth,                     D = IDay
They are working good as expected..

I just wondering why the first approach given is not working..
Kind Regards,
George Ananth. S | Prolog Developer
georgeananth.prolog@gmail.com
+91 9791499282
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls »

I cannot reproduce the problem.

Your second approach is a little strange, because time::new returns the current date+time and setDate only sets the date, but keeps the time as it is. This means that your code (potentially) works different at different times at the day.

Normally this should not matter, but for the dates that shift between daylight saving and not daylight saving there could be some percularities (and/or bugs).

Which time zone are you in?

Do you know if 2002-03-10 (or one of the surrounding days) happens to be a daylight-save change day?
Regards Thomas Linder Puls
PDC
User avatar
George
Active Member
Posts: 47
Joined: 19 Sep 2011 8:54

Unread post by George »

This has been tested with the US time...

Eastern Time Zone..

I'm not sure about the daylight changing in US..

Kindly advice.. how can i fix this issue...???
Kind Regards,
George Ananth. S | Prolog Developer
georgeananth.prolog@gmail.com
+91 9791499282
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls »

OK, I have reproduced the problem and it has to do with daylight saving (the problem will not exist in Vip 7.4), you can use the following code instead:

Code: Select all

class predicates     isValidDate : (integer Year, integer Month, integer Day) determ. clauses     isValidDate(Year, Month, Day) :-         T = time::newFromTimeZone(0, timeFormatter::timeZone("", 0, timeFormatter::noDaylightSaving)),         T:setDateAndTime(Year, Month, Day, 0, 0, 0),         T:getDate(Y, M, D),         Y = Year,         M = Month,         D = Day.
Regards Thomas Linder Puls
PDC
User avatar
George
Active Member
Posts: 47
Joined: 19 Sep 2011 8:54

time::isValidDate predicate was not working as expected

Unread post by George »

The built in time::isValidDate/3 predicate on 7.4 VIP is not working as expected.

Code

Code: Select all

time::isValidDate(2000,200,12),
Year : 2000
Month : 200 - invalid
Day : 12
The input to this predicate was invalid, still it was succeeding the call.

Can you please advice me why this built-in predicate was succeed instead of fail.. ?
Kind Regards,
George Ananth. S | Prolog Developer
georgeananth.prolog@gmail.com
+91 9791499282
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls »

Yes, something has gone wrong. Try this instead:

Code: Select all

class predicates     isValidDate : (integer Year, integer Month, integer Day) determ.     % @short Succeeds if #Year, #Month and #Day represents a valid date.     % @end clauses     isValidDate(Year, Month, Day) :-         0 < Month, Month <=12,         0< Day, Day <= time::getDaysInMonth(Year, Month).
Regards Thomas Linder Puls
PDC
User avatar
George
Active Member
Posts: 47
Joined: 19 Sep 2011 8:54

Unread post by George »

Can I use the one which you given before on the same post.?
(I think this has been discussed before).

Anyway, assuming that you can yourself split the string into the components and convert these to integers, the simplest way is to create a time object from the components, and then ask for the components of that time object. If they are the same the date is valid.
class predicates
isValidDate : (integer Year, integer Month, integer Day) determ.
clauses
isValidDate(Year, Month, Day) :-
time::newDate(Year, Month, Day):getDate(Y, M, D),
Y = Year,
M = Month,
D = Day.
Please advice if I can use the above code ?
Kind Regards,
George Ananth. S | Prolog Developer
georgeananth.prolog@gmail.com
+91 9791499282
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Unread post by Thomas Linder Puls »

Why not use this:

Code: Select all

class predicates     isValidDate : (integer Year, integer Month, integer Day) determ.     % @short Succeeds if #Year, #Month and #Day represents a valid date.     % @end clauses     isValidDate(Year, Month, Day) :-         0 < Month, Month <=12,         0< Day, Day <= time::getDaysInMonth(Year, Month).
Regards Thomas Linder Puls
PDC
Harrison Pratt
VIP Member
Posts: 439
Joined: 5 Nov 2000 0:01

Re: time::isValidDate predicate was not working as expected

Unread post by Harrison Pratt »

Perhaps it is _designed_ to test the validity of a future date (200 - CurrentMonth) a certain number of months into the future?

Can you get a valid date response if the input Month is negative (for a date before the current month)? If so, the designed function would seem to be to assess the validity of dates in the past and future using an offset of months, days or years relative to the current date.

If not both of the above, then it's a bug.

George wrote:The built in time::isValidDate/3 predicate on 7.4 VIP is not working as expected.

Code

Code: Select all

time::isValidDate(2000,200,12),
Year : 2000
Month : 200 - invalid
Day : 12
The input to this predicate was invalid, still it was succeeding the call.

Can you please advice me why this built-in predicate was succeed instead of fail.. ?
Post Reply