Solved String time to int

Discussion in 'Spigot Plugin Development' started by 6u5t4v, Feb 21, 2020.

  1. What is an effecient way of turning a string such as "1d 5h 2m 3s" into an integer for a cooldown. Without having to use all 4 parameter, but can maybe just do "4h 4s"
     
  2. You can try this code :
    Code (Text):
    SimpleDateFormat ft = new SimpleDateFormat("dd'd' hh'h' mm'm' ss's'");
            try {
                Date date = ft.parse("1d 5h 2m 3s");
                System.out.println(date.getHours()+"h "+date.getSeconds()+"s"); //We can get the hour and seconds
                date.setHours(date.getHours()+1); // It's possible to modify time
                System.out.println(date.getHours()+"h "+date.getSeconds()+"s");
            } catch (ParseException e) {
                e.printStackTrace();
            }
     
  3. Nice! but how do I convert the parsed in string to an integer in the form of seconds
     
  4. You can try something like this :
    Code (Text):
    SimpleDateFormat ft = new SimpleDateFormat("d'd' hh'h' mm'm' ss's'");
            try {
                Date date = ft.parse("1d 5h 2m 3s");
               
                Calendar cal = Calendar.getInstance();
                cal.setTime(date);
               
                int seconds = cal.get(Calendar.DAY_OF_MONTH) * 86400 + date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds();
                System.out.println("Seconds : "+seconds);
            } catch (Exception e) {
                e.printStackTrace();
            }
     
  5. I get this error

    Code (Java):
    java.text.ParseException: Unparseable date: "3h"
    [14:23:41] [Server thread/WARN]:     at java.text.DateFormat.parse(Unknown Source)
    I know why it. So how do I do so i dont have to input "xd xh xm xs", but allow just putting fx: "3h"

    this is code
    Code (Java):
    public static int convertCooldownToSeconds(String str) {
            int cooldownTime = 0;
            SimpleDateFormat ft = new SimpleDateFormat("dd'd' hh'h' mm'm' ss's'");
            try {
                // str looks like "5d 2h 1m 4s"
                Date date = ft.parse(str);

                Calendar cal = Calendar.getInstance();
                cal.setTime(date);

                cooldownTime = cal.get(Calendar.DAY_OF_MONTH) * 86400 + date.getHours() * 3600 + date.getMinutes() * 60
                        + date.getSeconds();

            } catch (ParseException e) {
                e.printStackTrace();
            }

            return cooldownTime;
        }
    And how would I put an integer in, and have converted to a string with same format, fx: putting 86400 in then getting the cooldown string format "0d 1h 0m 0s"
     
    #5 6u5t4v, Feb 21, 2020
    Last edited: Feb 21, 2020
  6. With SimpleDateFormat you need to follow the format. You can't put "3h" you need to put "0d 3h 0m 0s". But if you want an alternative :
    Code (Text):

    public static int convertCooldownToSeconds(String str) {
            int cooldownTime = 0;
           
            String[] split = str.split(" ");
           
            for(String time : split) {
                char key = time.charAt(1);
                int value = Integer.parseInt(""+time.charAt(0));
               
                if(time.length() >= 3) {
                    key = time.charAt(2);
                    value = Integer.parseInt(""+time.charAt(0) + time.charAt(1));
                }
               
                if(key == 'd') {
                    cooldownTime += value * 86400;
                }
                if(key == 'h') {
                    cooldownTime += value * 3600;
                }
                if(key == 'm') {
                    cooldownTime += value * 60;
                }
                if(key == 's') {
                    cooldownTime += value;
                }
            }

            return cooldownTime;
        }
     
    With this function you can use convertCooldownToSeconds("3h")
     
    #6 besuper, Feb 21, 2020
    Last edited: Feb 21, 2020
  7. That is almost exactly my first solution xD, but this looks better, however can you help with the reverse process from seconds to the formatted string
     
  8. Format seconds to string
    Code (Text):
    public static String convertSecondsToCooldown(int seconds) {
            String format = "";
           
            if(seconds >= 86400) {
                int day = seconds / 86400;
                seconds -= day*86400;
                format += day+"d ";
            }
           
            if(seconds >= 3600) {
                int day = seconds / 3600;
                seconds -= day*3600;
                format += day+"h ";
            }
           
            if(seconds >= 60) {
                int day = seconds / 60;
                seconds -= day*60;
                format += day+"m ";
            }
           
            if(seconds <= 59) {
                format += seconds+"s";
            }
           
            return format;
        }
     
  9. Add
    [ optional section start
    ] optional section end

    See the modified example below. Getting milliseconds is also the better way.
    Keep in mind that optional date format parameter were added in Java 8.

    Edit: New changes with working mills diff
    Code (Text):


    DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern(
            "[d'd'][ ][h'h'][ ][m'm'][ ][s's']").appendPattern( "[d'd'][ ][hh'h'][ ][mm'm'][ ][ss's']").toFormatter();

    TemporalAccessor temporalAccessor = formatter.parse("1d 5h 2m 3s");
    System.out.println(temporalAccessor.toString());

    LocalDateTime time = LocalDateTime.now();
    LocalDateTime t2 = time
            .minus(ChronoField.DAY_OF_MONTH.getFrom(temporalAccessor), ChronoUnit.DAYS)
            .minus(ChronoField.HOUR_OF_AMPM.getFrom(temporalAccessor), ChronoUnit.HOURS)
            .minus(ChronoField.MINUTE_OF_HOUR.getFrom(temporalAccessor), ChronoUnit.MINUTES)
            .minus(ChronoField.SECOND_OF_MINUTE.getFrom(temporalAccessor), ChronoUnit.SECONDS);

    System.out.println("Seconds : "+ time.toEpochSecond(ZoneOffset.UTC) + "  t2: "+ t2.toEpochSecond(ZoneOffset.UTC));

     
     
    #9 ysl3000, Feb 21, 2020
    Last edited: Feb 21, 2020
    • Informative Informative x 1
  10. The optional stuff doesnt still getting same as here:
     
  11. See my edit above. This works.
     
  12. Not really sure what I suppose to return, since I need to return long or int as the cooldown
     
  13. Code (Java):
    DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern(
                    "[d'd'][ ][h'h'][ ][m'm'][ ][s's']").appendPattern("[d'd'][ ][hh'h'][ ][mm'm'][ ][ss's']").toFormatter();

            TemporalAccessor temporalAccessor = formatter.parse("1d 5h 2m 3s");
            System.out.println(temporalAccessor.toString());

            LocalDateTime time = LocalDateTime.now();
            LocalDateTime t2 = time
                    .minus(ChronoField.DAY_OF_MONTH.isSupportedBy(temporalAccessor) ? ChronoField.DAY_OF_MONTH.getFrom(temporalAccessor) : 0, ChronoUnit.DAYS)
                    .minus(ChronoField.HOUR_OF_AMPM.isSupportedBy(temporalAccessor) ? ChronoField.HOUR_OF_AMPM.getFrom(temporalAccessor) : 0, ChronoUnit.HOURS)
                    .minus(ChronoField.MINUTE_OF_HOUR.isSupportedBy(temporalAccessor) ? ChronoField.MINUTE_OF_HOUR.getFrom(temporalAccessor) : 0, ChronoUnit.MINUTES)
                    .minus(ChronoField.SECOND_OF_MINUTE.isSupportedBy(temporalAccessor) ? ChronoField.SECOND_OF_MINUTE.getFrom(temporalAccessor) : 0, ChronoUnit.SECONDS);


            long coolDownTimeSeconds = time.toEpochSecond(ZoneOffset.UTC) - t2.toEpochSecond(ZoneOffset.UTC);

            System.out.println("Seconds : " + coolDownTimeSeconds);
     
    • Informative Informative x 1
  14. It seems to work perfectly :) THANKS!