1

I'm updating data using execute anonymous (one-time update). The business wants me to replace date fields with picklist fields under a custom object called Category. The new picklist field should contain the month from the date field.

For instance, the example below. Start Date Old is the date field with a value of 12/1/2020. I am to update Start Date New with a value of December. I have to do this for 4 fields.

Start Date Old = 12/1/2020 (date field)
Start Date New = December (picklist field)

So far I was able to do the following:

//get all category records with Acceptance Date, End Date, Start Date, Reset Date not null (date fields)
List<Category__c> listOfCategories = [SELECT id, Acceptance_Date_Old__c, Acceptance_Date__c,Annual_Category_Review_End_Date__c,Annual_Category_Review_End_Date_Old__c,Reset_Date_Old__c,Annual_Category_Review_Start_Date__c,Annual_Category_Review_Start_Date_Old__c
                                     FROM Category__c
                                      WHERE Acceptance_Date_Old__c != NULL 
                                     OR Annual_Category_Review_End_Date_Old__c != NULL
                                     OR Reset_Date_Old__c != NULL
                                     OR Annual_Category_Review_Start_Date__c != NULL
                                     ];

system.debug('# of categories ' + listOfCategories.size());

for(Category__c c: listOfCategories){
    if(c.Acceptance_Date_Old__c != null){
        if(c.Acceptance_Date_Old__c.month() == 1){
            c.Acceptance_Date__c = 'January';
            
        }
        else if(c.Acceptance_Date_Old__c.month() == 2){
            c.Acceptance_Date__c = 'February';
        }
        else if(c.Acceptance_Date_Old__c.month() == 3){
            c.Acceptance_Date__c = 'March';
        }
        else if(c.Acceptance_Date_Old__c.month() == 4){
            c.Acceptance_Date__c = 'April';
        }
        else if(c.Acceptance_Date_Old__c.month() == 5){
            c.Acceptance_Date__c = 'May';
        }
        else if(c.Acceptance_Date_Old__c.month() == 6){
            c.Acceptance_Date__c = 'June';
        }
        else if(c.Acceptance_Date_Old__c.month() == 7){
            c.Acceptance_Date__c = 'July';
        }
        else if(c.Acceptance_Date_Old__c.month() == 8){
            c.Acceptance_Date__c = 'August';
        }
        else if(c.Acceptance_Date_Old__c.month() == 9){
            c.Acceptance_Date__c = 'September';
        }
        else if(c.Acceptance_Date_Old__c.month() == 10){
            c.Acceptance_Date__c = 'October';
        }
        else if(c.Acceptance_Date_Old__c.month() == 11){
            c.Acceptance_Date__c = 'November';
        }
        else if(c.Acceptance_Date_Old__c.month() == 12){
            c.Acceptance_Date__c = 'December';
        }
        
    }
    
    if(c.Annual_Category_Review_End_Date_Old__c != null){
        if(c.Annual_Category_Review_End_Date_Old__c.month() == 1){
            c.Annual_Category_Review_End_Date__c = 'January';
        }
        else if(c.Annual_Category_Review_End_Date_Old__c.month() == 2){
            c.Annual_Category_Review_End_Date__c = 'February';
        }
        else if(c.Annual_Category_Review_End_Date_Old__c.month() == 3){
            c.Annual_Category_Review_End_Date__c = 'March';
        }
        else if(c.Annual_Category_Review_End_Date_Old__c.month() == 4){
            c.Annual_Category_Review_End_Date__c = 'April';
        }
        else if(c.Annual_Category_Review_End_Date_Old__c.month() == 5){
            c.Annual_Category_Review_End_Date__c = 'May';
        }
        else if(c.Annual_Category_Review_End_Date_Old__c.month() == 6){
            c.Annual_Category_Review_End_Date__c = 'June';
        }
        else if(c.Annual_Category_Review_End_Date_Old__c.month() == 7){
            c.Annual_Category_Review_End_Date__c = 'July';
        }
        else if(c.Annual_Category_Review_End_Date_Old__c.month() == 8){
            c.Annual_Category_Review_End_Date__c = 'August';
        }
        else if(c.Annual_Category_Review_End_Date_Old__c.month() == 9){
            c.Annual_Category_Review_End_Date__c = 'September';
        }
        else if(c.Annual_Category_Review_End_Date_Old__c.month() == 10){
            c.Annual_Category_Review_End_Date__c = 'October';
        }
        else if(c.Annual_Category_Review_End_Date_Old__c.month() == 11){
            c.Annual_Category_Review_End_Date__c = 'November';
        }
        else if(c.Annual_Category_Review_End_Date_Old__c.month() == 12){
            c.Annual_Category_Review_End_Date__c = 'December';
        }
        
    }
    
}
update listOfCategories;

It works but only for 2 fields. There's got to be a better way. Any help is greatly appreciated. Thank you!!

1

You can get the text name of a month based on a Date instance by converting it to a Datetime and formatting it with SimpleDateFormat.

public static String getMonthName(Date value)
{
    return Datetime.newInstance(value, Time.newInstance(0, 0, 0, 0)).format('MMMM');
}
3
  • Thanks for responding.....I'm getting an error message at the method System.TypeException: Invalid date/time: Thu Mar 01 00:00:00 GMT 2018. Below is my code public static String getMonthName(Date value) { return Datetime.valueOf(value).format('MMMM'); } system.debug('# of categories ' + listOfCategories.size()); for(Category__c c: listOfCategories){ if(c.Reset_Date_Old__c != null){ c.Reset_Date__c = getMonthName(c.Reset_Date_Old__c); } } My apologies for the format. I'm new to this website. – Pearson Dec 7 '20 at 22:24
  • @Pearson Datetime.valueOf() can't take a Date, something that still boggles me to this day. Replacing that with Datetime.newInstance(value, Time.newInstance(0, 0, 0, 0)) will make this approach work. – Derek F Dec 7 '20 at 22:51
  • @DerekF that did it. Thank you! – Pearson Dec 7 '20 at 23:33
1

Adrian's answer is definitely the way to go.

If, for some reason you don't want to use that approach (or if you occasionally enjoy finding other solutions/approaches) there are a few other ways to go about this.

One alternative approach would be to use a switch statement. It pretty much translates into the same if/else structure you have now, but saves some typing

public static String getMonthName(Integer month){
    String monthName;
    switch on month{
        when 1 { monthName = 'January';}
        when 2 { monthName = 'February';}
        when 3 { monthName = 'March';}
        when 4 { monthName = 'April';}
        when 5 { monthName = 'May';}
        when 6 { monthName = 'June';}
        when 7 { monthName = 'July';}
        when 8 { monthName = 'August';}
        when 9 { monthName = 'September';}
        when 10 { monthName = 'October';}
        when 11 { monthName = 'November';}
        when 12 { monthName = 'December';}
        when else { monthName = null;}
    }
}

Since month names aren't going to change (at least I hope not), providing this functionality as a method makes a lot of sense (you want your code to be DRY (Don't Repeat Yourself), as opposed to WET (Write Everything Twice)).

The other approach I have in mind is a way that we can eliminate the if/else structure entirely by using a List or Map. This can't be done all the time, but this is one of the times where we can use this approach.

public static String getMonthName(Integer month){
    // This list could be initialized on a single line (or fewer lines)
    // Just writing this out on separate lines to help make a point
    List<String> monthNames = new List<String>{
        null,        // index 0
        'January',   // index 1
        'February',  // index 2
        'March',     // index 3
        'April',     // index 4
        'May',       // index 5
        'June',      // index 6
        'July',      // index 7
        'August',    // index 8
        'September', // index 9
        'October',   // index 10
        'November',  // index 11
        'December'   // index 12
    };

    // Ok, so we didn't _completely_ eliminate the if/else
    // Just a little data checking to avoid errors (though you may want
    //   to throw an exception so you get a helpful error message instead)
    if(month == null || month < 1 || month > 12){ return null; }

    // The integer month number can be used to index into a List
    return monthNames[month];
}

You could augment both approaches by using custom labels instead of string literals (which would help with internationalization).

Once again, Adrian's approach is the one you should use.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.