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

Allow escaping of characters in format() #35

Closed
cynddl opened this issue Aug 27, 2013 · 20 comments · Fixed by #688
Closed

Allow escaping of characters in format() #35

cynddl opened this issue Aug 27, 2013 · 20 comments · Fixed by #688

Comments

@cynddl
Copy link
Contributor

cynddl commented Aug 27, 2013

In French, hours are formatted as "8 h 40" and not as "8:40". But in an arrow's format string, h displays directly the hours. Would it be possible to add a key (such as !) to force h to be displayed normally ("hh !h mm")?

@crsmithdev
Copy link
Collaborator

Interesting. This will be a little more than a quick fix, as I'll have to move a little bit more formatting logic into the locale itself. Should be straightforward, though.

@bsidhom
Copy link
Contributor

bsidhom commented Sep 22, 2013

This sounds like a useful feature. Is using a ! standard for escaping literal characters? Could you link to some other libraries that do this?

@cynddl
Copy link
Contributor Author

cynddl commented Sep 22, 2013

Hi Ben,

! is not really conventional. MomentJS uses brackets to escape characters:

moment().format('[today] DDDD'); // 'today Sunday'

I think it will be a better idea, it's safer and easy to remember.

@bsidhom
Copy link
Contributor

bsidhom commented Sep 23, 2013

That definitely looks more convenient for escaping long strings (compare with !t!o!d!a!y). Unfortunately, the Python re module doesn't natively support atomic matching, so it makes for some messy regular expressions in dealing with bracket escaping. I've added a quick fix here. In particular, this line is what concerns me. I've included a more concise solution above it, but it's not preferable as it allows for backtracking between the parentheses and might behave badly on long escaped sequences. (See here to read about atomic matching and this StackOverflow post to understand the workaround.)

If you guys are OK with this (stylistically), then I'll go ahead and add some documentation and tests and submit a pull request.

NOTE: I've also removed an accidental duplicate line from the parser.

@crsmithdev
Copy link
Collaborator

This seems to be the right approach in general (using square brackets). The implementation in moment.js (https://github.com/moment/moment/blob/develop/moment.js#L29) is similar, and looks sane to me. I'll probably tweak / test the regex a bit on merge to make sure it's as efficient as possible.

@bsidhom
Copy link
Contributor

bsidhom commented Oct 2, 2013

That's interesting. I hadn't thought to look at the moment.js implementation, but upon inspection it looks like their regex doesn't allow for literal brackets within an escaped sequence. The regex in the commit I've linked to does so, and without exponential backtracking. We may or may not want to refine it to make sure that it's not doing superfluous checks though. I don't really know what nesting and literal [ escaping behavior should be, but I feel like it should at least allow for literal brackets themselves.

@oryband
Copy link

oryband commented Mar 9, 2015

👍

@sametmax
Copy link
Contributor

Got the same problem today, and had to to d.datetime.strftime. Which sucked cause it doesn't handle unicode properly in 2.7. BTW, why do we have different operators to format with arrow and datetime ? It should be the same. %stuff works well, and identify easily what's marker and what's not.

@allanlewis
Copy link

Same issue here - I'd like to format as "[date] at [time]", e.g. "Fri 01 May 2015 �at 16:32", but the 'a' gets translated into AM/PM.

@sukrit007
Copy link

👍 for square bracket support.

@andrewelkins
Copy link
Contributor

I like the bracket approach. I don't have time at the moment to make the PR for it though, does anyone else. I'd happily review and merge a PR with this.

@lgaticaq
Copy link

👍

1 similar comment
@ComFreek
Copy link

ComFreek commented Sep 8, 2015

👍

@AndydeCleyre
Copy link

I wouldn't mind throwing a \ before each escaped character, but I would love to have this feature in whatever form.

@AlJohri
Copy link

AlJohri commented Oct 10, 2016

👍 this would be amazing

@jdppettit
Copy link

👍

1 similar comment
@aGHz
Copy link

aGHz commented Nov 22, 2016

👍

@andrewelkins
Copy link
Contributor

Time to tackle this one 👍

@karbassi
Copy link

karbassi commented Jan 9, 2017

Seems like #290 could be used to help with this process.

@systemcatch
Copy link
Collaborator

systemcatch commented Jan 9, 2019

This now basically works for parsing but not for formatting.

Python 3.6.7 (default, Oct 25 2018, 09:16:13) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import arrow
>>> date_format = "YYYY-MM-DD h [h] m"
>>> my_date = "2018-03-09 8 h 40"
>>> arw=arrow.get(my_date, date_format)
<Arrow [2018-03-09T08:40:00+00:00]>
>>> arw.format(date_format)
'2018-03-09 8 [8] 40'

But it's not documented anywhere on https://arrow.readthedocs.io/en/latest/ so that needs to be fixed.

EDIT: updated that this does not working for formatting.

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

Successfully merging a pull request may close this issue.