Skip to Content
Technical Articles
Author's profile photo Vicenç Xavier Lozano

Date formatter class

Intro

How many times did you need some sort of format(date, “ddMMYYYY”) thing in ABAP? I did a lot.

And how many times did you build a class/function/program to do that? I did a few.

 

I’m pretty sure everybody has one of these (I had, twice, in the past), but I’ve had to build it for the third time today, and I thought “why don’t you share it?”.

Mostly because I’m a cool guy, not because I need some sort of “repository”.

If anyone feels the urge to create a GIT for it, feel free to do it, I will not claim authority nor anything else, I’m happy with the amount of attention (and responsability) I currently have.

 

Apologies

Mainly to Paul Hardy because I builded it ignoring TDD. It’s legacy code, mate, I know it, but I’m still trying to be used to TDD when it “doesn’t feel needed” (sorta “direct code” things).

And to Matthew Billingham because I did not used the whole new ABAP syntax (same reason).

And to anyone who reads this and points me to an error code or who will feird weird reading it.

I had to use CONCATENATE because I needed to respect blanks. String operators didn’t work (or I could not make them work).

All are my faults. Sorry.

The fact the post and the code box are too narrow for any 80s and latter screens are not my fault. It’s SAP’s. Sue them. If you dare. I don’t. Really.

 

How-to

It’s ease, the main method of the class is the formatter one. It will process any date (no, no valid checks -yet-) and any string for format it. The method will split the string into pieces, looking for

  • dd – day of the month
  • tt – number of the month
  • mm – short month name (three letters)
  • MM – full month name
  • yy – short year (last two positions)
  • YY – full year
  • ww – short weekday name (two letters)
  • WW – full weekday name

and will keep the rest “in place”.

 

To be helpful (for me, hence I just added the languages I need), I added two more methods with the standard language formats (I found via google translator, so they can be wrong). Feel free to pass me more date formats, I will gladly update them.

 

Last thoughts

The code comes “as is”, no warrants of any kind, and I will not accept any responsability if you use it and something goes wrong. If it contains any malware, it’s not me, someone has editted it to include the evil thing on it.

Please, feel free to:

  • use/copy it for free (but don’t try to get points for it, it’ll be rude)
  • create the git, as I said at the beginning
  • point me possible mistakes
  • suggest me possible improvements
  • build the tests

I will gladly (I love this word, that means “if I want”, but sounds like “happily”) apply the changes to my code and to this blog entry (if I’m still around and not formermemberized).

 

The code

class zcl_date_tools definition
  public
  abstract
  create public .

  public section.
    class-methods:
      formatdate 
        importing 
          date                  type dats 
          language              type sylangu default sy-langu 
          format                type csequence 
        returning value(result) type string,
      w 
        importing 
          date                  type dats 
          language              type sylangu default sy-langu 
        returning value(result) type string,
      m 
        importing 
          date                  type dats 
          language              type sylangu default sy-langu 
        returning value(result) type string,
      daysofweek 
        importing 
          language              type sylangu default sy-langu 
        returning value(result) type isu_t_days,
      mediumformat 
        importing 
          language              type sylangu default sy-langu 
        returning value(result) type string,
      longformat 
        importing 
          language              type sylangu default sy-langu 
        returning value(result) type string.
  protected section.
  private section.
    class-methods:
      allbutlasttwo 
        importing 
          text                     type csequence 
        returning value(resultado) type string,
      lasttwo 
        importing 
          text                     type csequence 
        returning value(resultado) type text02.
endclass.

class zcl_date_tools implementation.
  method formatdate.
    data: position type i,
          element type string.

    if format cs 'ww' or format cs 'WW'.
      data(w) = w( date = date language = language ).
    endif.
    if format cs 'mm' or format cs 'MM'.
      data(m) = m( date = date language = language ).
    endif.

    do strlen( format ) times.
      position = sy-index - 1.
      concatenate element format+position(1) into element respecting blanks.
      data(beginswith) = allbutlasttwo( element ).
      data(endswith) = lasttwo( element ).
      case endswith.
        when 'dd'.
          result = |{ result }{ beginswith }{ date+6(2) }|.
        when 'nn'.
          result = |{ result }{ beginswith }{ date+4(2) }|.
        when 'mm'.
          result = |{ result }{ beginswith }{ m(3) }|.
        when 'MM'.
          result = |{ result }{ beginswith }{ m+4 }|.
        when 'yy'.
          result = |{ result }{ beginswith }{ date+2(2) }|.
        when 'YY'.
          result = |{ result }{ beginswith }{ date(4) }|.
        when 'ww'.
          result = |{ result }{ beginswith }{ w(2) }|.
        when 'WW'.
          result = |{ result }{ beginswith }{ w+3 }|.
        when others.
          continue.
      endcase.
      free element.
    enddo.
  endmethod.

  method w.
    data: long type t246-langt,
          short type t246-kurzt.
    call function 'GET_WEEKDAY_NAME'
      exporting
        date        = date
        language    = language
      importing
        longtext    = long
        shorttext   = short
      exceptions
        calendar_id = 1
        date_error  = 2
        not_found   = 3
        wrong_input = 4
        others      = 5.
    if sy-subrc <> 0.
      return.
    endif.
    result = |{ short }-{ long }|.
  endmethod.

  method m.
    data: months type standard table of t247 with empty key.

    call function 'MONTH_NAMES_GET'
      exporting
        language              = language
      tables
        month_names           = months
      exceptions
        month_names_not_found = 1
        others                = 2.
    if sy-subrc <> 0.
      return.
    endif.
    result = |{ months[ date+4(2) ]-ktx }-{ months[ date+4(2) ]-ltx }|.
  endmethod.

  method daysofweek.
    call function 'WEEKDAY_GET'
      exporting
        language = language
      tables
        weekday  = result.
  endmethod.

  method lasttwo.
    check strlen( text ) >= 2.
    data(start) = strlen( text ) - 2.
    resultado = text+start.
  endmethod.

  method allbutlasttwo.
    check strlen( text ) >= 2.
    data(length) = strlen( text ) - 2.
    resultado = text(length).
  endmethod.

  method mediumformat.
    case language.
      when 'S' or 'ES'. "26 de julio de 2021
        result = 'dd de MM de YY'.
      when 'E' or 'EN'. "July 26, 2021
        result = 'MM dd, YY'.
      when 'L' or 'PL'. "26 lipca 2021
        result = 'dd MM YY'.
      when '느' or '1P'. "26 de julho de 2021
        result = 'dd de MM de YY'.
      when '4' or 'RO'. "26 iulie 2021
        result = 'dd de MM de YY'.
      when 'F' or 'FR'. "26 juillet 2021
        result = 'dd MM YY'.
    endcase.
  endmethod.

  method longformat.
    case language.
      when 'S' or 'ES'. "sábado, 26 de julio de 2021
        result = 'WW, dd de MM de YY'.
      when 'E' or 'EN'. "Saturday, July 26, 2021
        result = 'WW, MM dd, YY'.
      when 'L' or 'PL'. "sobota, 26 lipca 2021
        result = 'WW, dd MM YY'.
      when '느' or '1P'. "Sábado, 26 de julho de 2021
        result = 'WW, dd de MM de YY'.
      when '4' or 'RO'. "Sâmbătă, 26 iulie 2021
        result = 'WW, dd de MM de YY'.
      when 'F' or 'FR'. "samedi 26 juillet 2021
        result = 'WW dd MM YY'.
    endcase.
  endmethod.
endclass.

Assigned Tags

      16 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Matthew Billingham
      Matthew Billingham

      Aside from the formatting of the method definitions (maybe a problem with the blog editor?),

      class zcl_date_tools definition
        public
        abstract
        create public .
      
        public section.
          class-methods:
            formatdate 
              importing 
                date     type dats 
                language type sylangu default sy-langu 
                format   type csequence 
           returning value(result) type string,
           w 
             importing 
               date type dats 
               language type sylangu default sy-langu 
           returning 
             value(result) type string,
            m 
              importing 
                 date     type dats 
                 language type sylangu default sy-langu 
              returning 
                value(result) type string,
            daysofweek 
              importing language type sylangu default sy-langu 
            returning 
               value(result) type isu_t_days,
             mediumformat 
               importing 
                 language type sylangu default sy-langu 
              returning value(result) type string,
            longformat
               importing 
                 language type sylangu default sy-langu 
              returning value(result) type string,
        protected section.
        private section.
          class-methods:
            allbutlasttwo 
              importing 
                 text type csequence
              returning
                value(resultado) type string,
            lasttwo 
              importing
                text type csequence
              returning 
                value(resultado) type text02.
      endclass
      .

      it looks fine (date formatting will never be pretty), but first thing I'd do is to change all the static methods to instance.

      Reason?

      I'd like to do something like

      DATA(date_formatter) = NEW zcl_date_formatter( variable_containing_date_format ).

      Then I can use the same format on all my date output, instead of specifying it each time in method formatdate.

      I really recommend the CLEAN ABAP book. I've read it almost cover to cover, and learned new techniques and broken a few old (not good) habits.

      Author's profile photo Vicenç Xavier Lozano
      Vicenç Xavier Lozano
      Blog Post Author

      The editor has nothing to do with it, I arrange my methods that way... too crowded, maybe, but I don't care about the contract once I've "signed it". When I need to call the methods, Eclipse saves my butt, regardless of the crappy format of the original code.

      Not sure if it's right or wrong, just (atm) a matter of taste.

      About the removing of the class-methodology, I guess I understood your point, but I don't recall to have any app in need of multiple data format, so I decided to keep it that way.

      Author's profile photo Matthew Billingham
      Matthew Billingham

      I think if you're going to publish code for others, the signatures need to be readable. I want to look at it and understand it before putting it into my system

      But I think they need to be readable anyway. All code needs to be readable in my view. Certainly, if I came across this at 3am on a Sunday morning, and I knew where you lived... 😁

      Author's profile photo Vicenç Xavier Lozano
      Vicenç Xavier Lozano
      Blog Post Author

      Got the point, code kindly updated.

      Reward points if useful.

      Author's profile photo Matthew Billingham
      Matthew Billingham

      Tuly, points deducted. 😉

      Author's profile photo Sandra Rossi
      Sandra Rossi

      Don't you pretty print to align the parameter types? 😉

      Author's profile photo Vicenç Xavier Lozano
      Vicenç Xavier Lozano
      Blog Post Author

      I just edited the post and added the line feeds and spaces before the new lines... you dirty mind.

      But OK, just because of you and the patience you show to newbies, I'll pretty print them.

      Author's profile photo Vicenç Xavier Lozano
      Vicenç Xavier Lozano
      Blog Post Author

      Doh!... now it looks "professional"

      Author's profile photo Matthew Billingham
      Matthew Billingham

      Almost. Keyword upper case, underscores '_' between words ... 😁

      Author's profile photo Vicenç Xavier Lozano
      Vicenç Xavier Lozano
      Blog Post Author

      I kindly disagree, dude... no _ and all lowcase... I'd maybe consider the use of camelwhatever if the autoformatter was capable of, but underscores just "eat capacity"

      If you cannot understand productionorder but you can understand production_order, there's something wrong in you... only if the word could be split in two different sentences regarding where you put the space, but I did not find the case yet.

      Author's profile photo Matthew Billingham
      Matthew Billingham

      CamelCase is to be preferred of course. But for readability when not available, _ is adequate.

      You are fully entitled of course to your minority opinion 😁. At least they're better than prord... or lv_p1. 😮 😮

      In fact, the point the Clean Code authors make is true. There will never be consensus. I don't agree with everything they say either.

      Author's profile photo Sandra Rossi
      Sandra Rossi

      yey! 🙂

      Author's profile photo Vicenç Xavier Lozano
      Vicenç Xavier Lozano
      Blog Post Author

      humm... what about a "wrapper"?

      an instance where the instanced methods will call the static ones... sounds dirty.

      (o, about the book, I'm still learning from the rocket one)

      Author's profile photo Matthew Billingham
      Matthew Billingham

      You could use a wrapper of course. Still dirty.

      I did used to write static methods only classes, but got bitten a few times, so now I seldom have static methods, except possible the class constructor.

      I think you might well find the clean abap code book more useful - it's funny, but it's also not a bad way of learning the >= 7.40 ABAP. As I said, I learned things. 😁

      (I also learned to day how to view the list when you're WRITING, in the new debugger - on SAPGui of course).

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva

      Why there is no standard class that does all this and is released to everyone? SAP keeps boasting about API Hub yet here we are, Community writing custom code for the basic functionality. Yay for Community, boo for SAP.

      Author's profile photo Vicenç Xavier Lozano
      Vicenç Xavier Lozano
      Blog Post Author

      I'd be happy seeing SAP releasing something like that, even copying my own code without giving me points.