When i enter for example 08.04.1986

the Profile shows 08.04.y

When i change line 279 in profile.module from
'Y' => $value['year'],
to
'y' => $value['year'],

everything works fine.

Comments

Craftsman’s picture

Version: 6.6 » 6.9
Issue tags: +format_date

I have the same issue with 6.9. I use custom date format with ‘y’ format character (specifically – ‘d.m.y H:I’).
But script form.inc - function expand_date() and script profile.module function profile_view_field() doesn’t support ‘y’. Therefore I get 08.04.y on profile form and wrong order of select boxes of date input field.

Is it possible to add support for that kind of custom date format?

matt v.’s picture

Version: 6.9 » 7.x-dev

I've confirmed that the same issue exists in the development version of D7.

aspilicious’s picture

How do you reproduce this?
Is it as easy as the topic poster suggest?

sivaji_ganesh_jojodae’s picture

Status: Active » Needs review
StatusFileSize
new1.02 KB

This bug still exists. To reproduce

1. Add a custom date format say d.m.y H:I from admin/config/regional/date-time/formats.
2. Set the short date type to d.m.y H:I.
3. Now in the profile page (/user) you can see 08.04.1986 instead of 08.04.y

It is not document anywhere that profile date type uses short date type :P i found it myself by looking at the code.

function profile_view_field() in profile.module

      case 'date':
        $format = substr(variable_get('date_format_short', 'm/d/Y - H:i'), 0, 5);
        // Note: Avoid PHP's date() because it does not handle dates before
        // 1970 on Windows. This would make the date field useless for e.g.
        // birthdays.
        $replace = array(
          'd' => sprintf('%02d', $value['day']),
          'j' => $value['day'],
          'm' => sprintf('%02d', $value['month']),
          'M' => map_month($value['month']),
          'Y' => $value['year'],
          'H:i' => NULL,
          'g:ia' => NULL,
        );
        return strtr($format, $replace);

Attached patch adds code to support character format 'y' and 'D'.

jcisio’s picture

Status: Needs review » Needs work

Well, there are two problems:
- It is undocumented that Profile date uses the (first 5 characters of) short date format.
- The emulation of date() function is incomplete, at least there is a 'n' option (month, numeric without leading zero).

nvahalik’s picture

I am curious as to why the comments in the source code remark to stay away from the date() function since it could cause problems on Windows yet, IIRC, gmmktime() will have the same problem.

A real solution here would be to use repeatable years. Since there are only 14 distinct combinations of years, we could map the years outside of date()'s ranges to a year inside the range and then swap the years back to actual date when outputting the date. In this way, we could just use date() and swap out the 'Y' and 'y' formatters (with, for instance, "\xFE and '\xFD') and then put the appropriately formatted years back in for those values.

Since the profile field here in question uses only years 1900-2050, could we just map those years to years in the range without worrying about < 1900 or > 2050?

nvahalik’s picture

Status: Needs work » Needs review
StatusFileSize
new2.27 KB

Attached is patch for calculated year. Works for all of the years that profile field supports. Per the comments, the only 4 date() format characters it doesn't handle are the ISO year 'o' and the 3 full date/time formatters ('c', 'r', 'U'). I imagine it would not be hard to write a workaround for those.

damien tournoud’s picture

Status: Needs review » Needs work

Let's fix that properly.

1. We need to add a "Day only" date format in addition to "Short", "Medium" and "Long"
2. We don't need the "Windows" fix, since the issue with timestamp < 0 has been fixed since PHP 5.1.0

jcisio’s picture

Oh, in that case, please add "time only", too. It's very useful for a list of latest things.

nvahalik’s picture

Status: Needs work » Needs review
StatusFileSize
new5.66 KB

This patch includes the following changes:

* Added date only and time only formats in system_date_format_types().
* Added a comprehensive set of date and time formats into includes/date.inc.
* profile.module has been updated to use the proper date format.
* Removed reference to windows workaround.

damien tournoud’s picture

Is there any reason not to simply use format_date() here?

jcisio’s picture

I think Damien is correct. This is a patch for D7, which requires PHP 5.2 where the Windows problem with negative timestamp was fixed.

With those changes, it is impossible to backport it into D6 ;)

nvahalik’s picture

StatusFileSize
new5.65 KB

Sorry, a bit of ignorance on my part! No, there is no reason not to use it. Patch updated to use format_date().

Status: Needs review » Needs work

The last submitted patch, 340506_profile_format_date.patch, failed testing.

nvahalik’s picture

StatusFileSize
new6.32 KB

Patched the test to use the new date as well.

nvahalik’s picture

Status: Needs work » Needs review

Setting to needs review.

damien tournoud’s picture

Thanks for the patch, this looks really fine now, except one thing:

+        return format_date(date_create("{$value['year']}-{$value['month']}-{$value['day']}")->format('U'), 'date');

Why not directly use mktime() here? Plus please add a comment explaining that because this timestamp (created by date_create() / mktime()) is created in the timezone of the user, the resulting date will always be displayed the same.

nvahalik’s picture

If you use mktime() here, any date before 1901-12-13 or after 2038-01-19 will cause mktime() to return bool(false). By using date_create() and format('U'), it will generate a valid 64-bit timestamp which format_date() will properly digest internally.

date_create()->format('U') should return a value in the same TZ that mktime() does. There should be no functional difference.

damien tournoud’s picture

If you use mktime() here, any date before 1901-12-13 or after 2038-01-19 will cause mktime() to return bool(false). By using date_create() and format('U'), it will generate a valid 64-bit timestamp which format_date() will properly digest internally.

The limitation of mktime() only applies to 32bit systems, and also applies to date_create()/format('U'). On 64bit systems, both methods generate a valid 64-bit timestamp for dates in an incredibly large time range :)

So let's switch to mktime() here, which is definitely quicker and easier to understand.

nvahalik’s picture

StatusFileSize
new6.47 KB

mktime() won't always work; you can't trust that PHP will be 64-bit.

Even on OS X 10.6, the OS says time_t is 64-bits, but PHP's maximum integer size is 32-bit. On a couple of different test systems mktime() still fails when called with years > 2038 and < 1901. date_create() will always work in this scenario. Added a comment to remove confusion.

thedavidmeister’s picture

Status: Needs review » Needs work

This patch no longer applies:

error: common.inc: No such file or directory
error: date.inc: No such file or directory
error: profile/profile.module: No such file or directory
error: profile/profile.test: No such file or directory
error: system/system.module: No such file or directory

nvahalik’s picture

Issue summary: View changes
Status: Needs work » Needs review
StatusFileSize
new5.59 KB

Updated patch to apply to latest version of Drupal.

Status: Needs review » Closed (outdated)

Automatically closed because Drupal 7 security and bugfix support has ended as of 5 January 2025. If the issue verifiably applies to later versions, please reopen with details and update the version.