Showing Morning, afternoon, evening, night message based on Time in java

67,430

Solution 1

You should be doing something like:

Calendar c = Calendar.getInstance();
int timeOfDay = c.get(Calendar.HOUR_OF_DAY);

if(timeOfDay >= 0 && timeOfDay < 12){
    Toast.makeText(this, "Good Morning", Toast.LENGTH_SHORT).show();        
}else if(timeOfDay >= 12 && timeOfDay < 16){
    Toast.makeText(this, "Good Afternoon", Toast.LENGTH_SHORT).show();
}else if(timeOfDay >= 16 && timeOfDay < 21){
    Toast.makeText(this, "Good Evening", Toast.LENGTH_SHORT).show();
}else if(timeOfDay >= 21 && timeOfDay < 24){
    Toast.makeText(this, "Good Night", Toast.LENGTH_SHORT).show();
}

Solution 2

For anyone who is looking for the latest Kotlin syntax for @SMA's answer, here is the helper function :

fun getGreetingMessage():String{
    val c = Calendar.getInstance()
    val timeOfDay = c.get(Calendar.HOUR_OF_DAY)

    return when (timeOfDay) {
           in 0..11 -> "Good Morning"
           in 12..15 -> "Good Afternoon"
           in 16..20 -> "Good Evening"
           in 21..23 -> "Good Night"
           else -> "Hello"
      }
    }

Solution 3

I would shorten your if/elseif statement to:

String greeting = null;
if(hours>=1 && hours<=12){
    greeting = "Good Morning";
} else if(hours>=12 && hours<=16){
    greeting = "Good Afternoon";
} else if(hours>=16 && hours<=21){
    greeting = "Good Evening";
} else if(hours>=21 && hours<=24){
    greeting = "Good Night";
}
Toast.makeText(this, greeting, Toast.LENGTH_SHORT).show();

Solution 4

java.time

I would advise to use Java 8 LocalTime.

Maybe create a class like this to handle your time of day problem.

public class GreetingMaker { // think of a better name then this.

  private static final LocalTime MORNING = LocalTime.of(0, 0, 0);
  private static final LocalTime AFTER_NOON = LocalTime.of(12, 0, 0);
  private static final LocalTime EVENING = LocalTime.of(16, 0, 0);
  private static final LocalTime NIGHT = LocalTime.of(21, 0, 0);

  private LocalTime now;

  public GreetingMaker(LocalTime now) {
    this.now = now;
  }

  public void printTimeOfDay() { // or return String in your case
    if (between(MORNING, AFTER_NOON)) {
      System.out.println("Good Morning");
    } else if (between(AFTER_NOON, EVENING)) {
      System.out.println("Good Afternoon");
    } else if (between(EVENING, NIGHT)) {
      System.out.println("Good Evening");
    } else {
      System.out.println("Good Night");
    }
  }

  private boolean between(LocalTime start, LocalTime end) {
    return (!now.isBefore(start)) && now.isBefore(end);
  }

}

Solution 5

Using Time4J (or Time4A on Android) enables following solutions which do not need any if-else-statements:

ChronoFormatter<PlainTime> parser =
    ChronoFormatter.ofTimePattern("hh:mm a", PatternType.CLDR, Locale.ENGLISH);
PlainTime time = parser.parse("10:05 AM");

Map<PlainTime, String> table = new HashMap<>();
table.put(PlainTime.of(1), "Good Morning");
table.put(PlainTime.of(12), "Good Afternoon");
table.put(PlainTime.of(16), "Good Evening");
table.put(PlainTime.of(21), "Good Night");
ChronoFormatter<PlainTime> customPrinter=
    ChronoFormatter
      .setUp(PlainTime.axis(), Locale.ENGLISH)
      .addDayPeriod(table)
      .build();
System.out.println(customPrinter.format(time)); // Good Morning

There is also another pattern-based way to let the locale decide in a standard way based on CLDR-data how to format the clock time:

ChronoFormatter<PlainTime> parser =
    ChronoFormatter.ofTimePattern("hh:mm a", PatternType.CLDR, Locale.ENGLISH);
PlainTime time = parser.parse("10:05 AM");

ChronoFormatter<PlainTime> printer1 =
    ChronoFormatter.ofTimePattern("hh:mm B", PatternType.CLDR, Locale.ENGLISH);
System.out.println(printer1.format(time)); // 10:05 in the morning

ChronoFormatter<PlainTime> printer2 =
    ChronoFormatter.ofTimePattern("B", PatternType.CLDR, Locale.ENGLISH)
        .with(Attributes.OUTPUT_CONTEXT, OutputContext.STANDALONE);
System.out.println(printer2.format(time)); // morning

The only other library known to me which can also do this (but in an awkward way) is ICU4J.

Share:
67,430

Related videos on Youtube

Devrath
Author by

Devrath

I work as a mobile Applications developer and specialize in Android and Flutter I learn by Sharing my knowledge and learning from others I'm a curious creature and like staying up to date with new technologies My Global stack-overflow ranking

Updated on April 10, 2022

Comments

  • Devrath
    Devrath about 2 years

    What i am trying to do::

    Show message based on

    • Good morning (12am-12pm)
    • Good after noon (12pm -4pm)
    • Good evening (4pm to 9pm)
    • Good night ( 9pm to 6am)

    CODE::

    I used 24-hr format to get this logic

    private void getTimeFromAndroid() {
            Date dt = new Date();
            int hours = dt.getHours();
            int min = dt.getMinutes();
    
            if(hours>=1 || hours<=12){
                Toast.makeText(this, "Good Morning", Toast.LENGTH_SHORT).show();
            }else if(hours>=12 || hours<=16){
                Toast.makeText(this, "Good Afternoon", Toast.LENGTH_SHORT).show();
            }else if(hours>=16 || hours<=21){
                Toast.makeText(this, "Good Evening", Toast.LENGTH_SHORT).show();
            }else if(hours>=21 || hours<=24){
                Toast.makeText(this, "Good Night", Toast.LENGTH_SHORT).show();
            }
        }
    

    Question:

    • Is this this best way of doing it, If no which is the best way
    • Yazan
      Yazan over 9 years
      @Devrath off-topic note, should'nt it be AND && , you are using OR || which will result all cases (hours >= 1) fall in Good Morning case?
    • Tom
      Tom over 9 years
      You should know, that the hours are in range between 0 and 23: getHours().
    • user987339
      user987339 over 9 years
      @Devrath I've updated the answer to take into account 12:59.
    • Basil Bourque
      Basil Bourque almost 5 years
      FYI, the troublesome date-time classes such as java.util.Date, java.util.Calendar, and java.text.SimpleDateFormat are now legacy, supplanted by the java.time classes. Most of the java.time functionality is back-ported to Java 6 & Java 7 in the ThreeTen-Backport project. Further adapted for earlier Android (<26) in ThreeTenABP. See How to use ThreeTenABP….
  • Devrath
    Devrath over 9 years
    [+1] for optimization
  • SMA
    SMA over 9 years
    Do you want at 12:59 a good morning or Good afternoon? You need to test @Devrath before accepting the answer.
  • Devrath
    Devrath over 9 years
    @ almas shaikh .... can you edit your answer for optimization as user987339 suggested ? ........ @ [+1] for user987339 for optimization
  • user987339
    user987339 over 9 years
    @ almas sheikh you were right. I've updated the answer for case of 12:59
  • Tom
    Tom over 9 years
    Well, it is not nice, that I won't get any greeting if hours is 0.
  • Tom
    Tom over 9 years
    Please read this JavaDoc.
  • Basil Bourque
    Basil Bourque over 9 years
    I would add an else case at the bottom to catch any unexpected value (defensive programming).
  • Joshua Pinter
    Joshua Pinter almost 7 years
    @BasilBourque Exactly. Even if it notifies your support team of a strange edge case. The key is to not let this crash the app since it's not mission critical.
  • Abed Putra
    Abed Putra almost 7 years
    getInstance(); need android api 24.
  • Basil Bourque
    Basil Bourque over 6 years
    That first clause in your between test predicate should be ( ! now.isBefore( start ) ) to handle the moment when now is start.
  • Basil Bourque
    Basil Bourque over 6 years
    Not sure if technically required, but I would put parens around that first clause to be safe and to be clear regarding the effect of the NOT “!”.
  • Basil Bourque
    Basil Bourque almost 5 years
    FYI, the troublesome date-time classes such as java.util.Date, java.util.Calendar, and java.text.SimpleDateFormat are now legacy, supplanted by the java.time classes. Most of the java.time functionality is back-ported to Java 6 & Java 7 in the ThreeTen-Backport project. Further adapted for earlier Android (<26) in ThreeTenABP. See How to use ThreeTenABP….
  • RalfFriedl
    RalfFriedl over 4 years
    Why is this better than the other answers? Not to mention that it doesn't implement the times of the question.
  • Ole V.V.
    Ole V.V. over 4 years
    Thanks for wanting to contribute. The question was tagged java, this means that a Java solution is asked for. Is yours C#? Also you’re not answering the question. It was: Is this this best way of doing it? If no, which is the best way?
  • Basil Bourque
    Basil Bourque about 4 years
    FYI, the terribly flawed date-time classes such as java.util.Date, java.util.Calendar, and java.text.SimpleDateFormat are now legacy, supplanted by the java.time classes built into Java 8 and later.
  • Scratte
    Scratte about 4 years
    The removal of the greater than parts make this look very similar to the solution by Jianqing GAO.
  • Basil Bourque
    Basil Bourque over 3 years
    Your approach has already been covered by Answers posted months ago. If yours is an improvement, edit to describe that improvement. If not, I suggest you delete the Answer.
  • Basil Bourque
    Basil Bourque over 3 years
    This code uses the terrible Calendar class that was supplanted years ago by the modern java.time classes. See the Answer by Nahar.
  • Ole V.V.
    Ole V.V. about 2 years
    It would be still simpler with LocalTime from java.time, the modern Java date and time API. Your code is as old-fashioned as possible.
  • Ole V.V.
    Ole V.V. about 2 years
    Also is there anything substantial here that isn’t already covered by the answers by donnicias and by Jianqing GAO?