Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug with a custom pattern on Date mask #100

Closed
caiotarifa opened this issue Sep 27, 2018 · 20 comments
Closed

Bug with a custom pattern on Date mask #100

caiotarifa opened this issue Sep 27, 2018 · 20 comments

Comments

@caiotarifa
Copy link

caiotarifa commented Sep 27, 2018

The user can't type the last number when I change the pattern to d/m/Y.

new IMask(element, { mask: Date, pattern: 'd/m/Y' })

Browser: Safari 11
Demo: https://jsfiddle.net/p2Lt5j3b/1/

@uNmAnNeR
Copy link
Owner

@caiotarifa you have to provide your custom format and parse options. Please take a look at examples in guide. There are a lot of date formats and it's not possible to handle them all in library. So this is application side task.

@caiotarifa
Copy link
Author

Yes, I read the documentation. I only want to replace the . by the / or -, the two most common separators for dates in the world.

@uNmAnNeR
Copy link
Owner

uNmAnNeR commented Oct 2, 2018

@caiotarifa Still It does not make sense to put it into mask library. Btw I believe that I even should not had to add default pattern with dots. I try to keep library size as small as possible and who does not care about size almost always use moment or luxon and it's very easy to provide date formatters.

@TonyE73
Copy link

TonyE73 commented Oct 7, 2018

Hi, I am having the same problem despite adding parse and format returns '2018-10-2' in input. Always leaves the last digit off. Other than this I am very impressed with the program

mask: Date,
parse: function (str) {var yearMonthDay = str.split('-');
return new Date(yearMonthDay[0], yearMonthDay[1] - 1, yearMonthDay[2]);
},
pattern: "Y-m-d",
dateFormat:"Y-m-d"

@uNmAnNeR
Copy link
Owner

uNmAnNeR commented Oct 7, 2018

@TonyE73 please also provide your format option. Please also check example in guide, it should work and very similar to your code.

@TonyE73
Copy link

TonyE73 commented Oct 7, 2018

OK, it is sorted. I just followed your instructions

mask: Date,
pattern: 'Y-m-d',
format: function (date) {
var day = date.getDate();
var month = date.getMonth() + 1;
var year = date.getFullYear();
if (day < 10) day = "0" + day;
if (month < 10) month = "0" + month;
return [year, month, day].join('-');
},
parse: function (str) {
var yearMonthDay = str.split('-');
return new Date(yearMonthDay[0], yearMonthDay[1] - 1, yearMonthDay[2]);
}

@uNmAnNeR
Copy link
Owner

uNmAnNeR commented Oct 8, 2018

@TonyE73 Check it works https://jsfiddle.net/o9gaydq8/

@evanjmg
Copy link

evanjmg commented Oct 11, 2019

@uNmAnNeR this solution is a hack and does not work like the other behaviour - please reopen and say this is a temporary workaround

@jaderss
Copy link

jaderss commented Jul 24, 2020

The problem still exists. I have the same problem with the date pattern right now.

@la-costa
Copy link

Hi,

This setting using luxon works for me.

It seems that the problem of last digit when an error occurs during the format or parse function.

import { DateTime } from "luxon";
const patternDate = 'dd/LL/yyyy';
const mask = {
	mask: Date,
	pattern: patternDate,
	format: function (date) {
	  return date.toLocaleString(patternDate);
	},
	parse: function (str) {
	  return DateTime.fromFormat(str, patternDate);
	},
	blocks: {
	  yyyy: {
		mask: IMask.MaskedRange,
		from: 1900,
		to: 2090,
	  },
	  LL: {
		mask: IMask.MaskedRange,
		from: 1,
		to: 12,
	  },
	  dd: {
		mask: IMask.MaskedRange,
		from: 1,
		to: 31,
	  },
	},
};

@la-costa la-costa mentioned this issue Jan 27, 2021
@marcoskichel
Copy link

Why is this issue closed if the problem is not fixed?

@echelonka
Copy link

Just got the same issue in react-native-imask but with pattern mm/dd/yyyy. Managed to fix it via date-fns:

import { IMaskTextInput } from 'react-native-imask';
import { format, parse } from 'date-fns';

const DateInput = () => {
  return (
    <IMaskTextInput
      mask={Date}
      pattern="m{/}`d{/}`Y"
      format={(date: Date): string => format(date, 'MM/dd/yyyy')}
      parse={(value: string): Date => parse(value, 'MM/dd/yyyy', new Date())}
    />
  );
};

Hope it will help someone!

@greenomac
Copy link

greenomac commented Mar 24, 2023

I solved it by changing the imask-6.4.3.js file, starting from line 2766 to 2784.

New code:

  MaskedDate.DEFAULTS = {
    pattern: 'd{/}`m{/}`Y',
    format: function format(date) {
      if (!date) return '';
      var day = String(date.getDate()).padStart(2, '0');
      var month = String(date.getMonth() + 1).padStart(2, '0');
      var year = date.getFullYear();
      return [day, month, year].join('/');
    },
    parse: function parse(str) {
      var _str$split = str.split('/'),
        _str$split2 = _slicedToArray(_str$split, 3),
        day = _str$split2[0],
        month = _str$split2[1],
        year = _str$split2[2];

      return new Date(year, month - 1, day);
    }
  };

@fellipefreiire
Copy link

keeps closing with the problem not being solved...

@uNmAnNeR
Copy link
Owner

@fellipefreiire i feel like the only problem here is that people are just do not want to read the docs. There is a way to extend the mask with any date/time pattern but instead of trying to figure it out people prefer to blame in the comments to make me do their work. Let me know if i am wrong and you or someone else has a real issue related to the library facilities that does not allow you to solve your problem. Otherwise i will continue to respectfully ignore these throws.

@ezze
Copy link

ezze commented Nov 16, 2023

I faced the similar issue and found this thread. If I got it right, the problem is that if I provide any custom pattern for date mask I also need to specify format and parse functions corresponding to it otherwise results will be unexpected like mentioned above.

@uNmAnNeR Maybe, docs should be a little bit more specific on this. Wouldn't it better to add typings constraints disallowing to pass non-default pattern without format and parse functions and throw an error if it's been passed?

@uNmAnNeR
Copy link
Owner

@ezze good idea about types, will check

lets make it red ? :)
image

@ezze
Copy link

ezze commented Dec 12, 2023

lets make it red ? :)

@uNmAnNeR Ha-ha, some lads including me should buy vision glasses. :) Although I was pretty sure that read the docs carefully.

Just for reference: https://imask.js.org/guide.html#masked-date

@jafar-alphaeon
Copy link

jafar-alphaeon commented Apr 18, 2024

I see where the confusion was, in the parse function you also have to realign your split date string accordingly. Typing the variables also helps, especially for date logic. Although, I used :any when passing into format

      <IMaskInput 
              mask={Date}
              pattern={'m/d/Y'}
              parse={ function (str) {
                var fullDate:string[] = str.split('/');
                  return new Date(
                    Number(fullDate[2]), // Year
                    Number(fullDate[0])-1,  // Month
                    Number(fullDate[1]),  // Day
                );
              }}
              format={(date:any)=>{
                var day:string = date.getDate().toString();
                var month:string = String(date.getMonth() + 1);
                var year = date.getFullYear();
                if (Number(day) < 10) day = "0" + day;
                if (Number(month) < 10) month = "0" + month;
               return [month, day, year].join('/')
              }}
             
              min={new Date(1950, 0, 1)}
              max={new Date(2020, 0, 1)}
              lazy={false}
              unmask={true}
            />

@asadulloh-pro
Copy link

asadulloh-pro commented May 6, 2024

Hi.

I prefer use dayjs for format and parse:

import dayjs from "dayjs";
import { IMask, IMaskInput } from "react-imask";

const configDate = () => ({
  d: {
    mask: IMask.MaskedRange,
    from: 1,
    to: 31,
    maxLength: 2,
  },
  m: {
    mask: IMask.MaskedRange,
    from: 1,
    to: 12,
    maxLength: 2,
  },
  Y: {
    mask: IMask.MaskedRange,
    from:  1919,
    to: 2030,
    maxLength: 4,
  },
});
const configTime = () => ({
  H: {
    mask: IMask.MaskedRange,
    from: 0,
    to: 23,
  },
  i: {
    mask: IMask.MaskedRange,
    from: 0,
    to: 59,
  },
});

const momentFormat = "YYYY-MM-DD HH:mm";

const DateTimeInput = () => {

const date = configDate( );

  const time = configTime();

  const dateBlocks = {
    ...date,
    separator: "-",
  };

  const timeBlocks = {
    ...time,
    separator: ":",
  };


return (
<IMaskInput
            mask={Date as any}
            inputRef={ref}
            lazy={false}
            pattern="Y-m-d H:i"
            autofix={true}
            blocks={{
              ...dateBlocks,
              ...timeBlocks,
            }}
            onAccept={onChange}
            value={value}
            format={(date) => dayjs(date).format(momentFormat)}
            parse={(str) => dayjs(str, momentFormat)}
            placeholder={placeholder}
          />
)

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests