diff --git a/usr.bin/ncal/ncal.1 b/usr.bin/ncal/ncal.1
index 598dbe4f5813..925c2b803ed9 100644
--- a/usr.bin/ncal/ncal.1
+++ b/usr.bin/ncal/ncal.1
@@ -99,7 +99,8 @@ note the year must be fully specified:
 will
 .Em not
 display a calendar for 1989.
-Two parameters denote the month (1 - 12) and year.
+Two parameters denote the month and year; the month is either a number between
+1 and 12, or a full or abbreviated name as specified by the current locale.
 .Pp
 A year starts on Jan 1.
 .Sh SEE ALSO
diff --git a/usr.bin/ncal/ncal.c b/usr.bin/ncal/ncal.c
index e10f45a3e4ab..4fa3fd4b82f4 100644
--- a/usr.bin/ncal/ncal.c
+++ b/usr.bin/ncal/ncal.c
@@ -162,6 +162,7 @@ char   *center(char *s, char *t, int w);
 void	mkmonth(int year, int month, int jd_flag, struct monthlines * monthl);
 void    mkmonthb(int year, int month, int jd_flag, struct monthlines * monthl);
 void    mkweekdays(struct weekdays * wds);
+int     parsemonth(const char *s);
 void    printcc(void);
 void    printeaster(int year, int julian, int orthodox);
 void    printmonth(int year, int month, int jd_flag);
@@ -306,9 +307,11 @@ main(int argc, char *argv[])
 	case 2:
 		if (flag_easter)
 			usage();
-		m = atoi(*argv++);
+		m = parsemonth(*argv++);
 		if (m < 1 || m > 12)
-			errx(EX_USAGE, "month %d not in range 1..12", m);
+			errx(EX_USAGE,
+			    "%s is neither a month number (1..12) nor a name",
+			    argv[-1]);
 		/* FALLTHROUGH */
 	case 1:
 		y = atoi(*argv++);
@@ -848,3 +851,20 @@ center(char *s, char *t, int w)
 	sprintf(s, "%.*s%s", (int)(w - strlen(t)) / 2, blanks, t);
 	return (s);
 }
+
+int
+parsemonth(const char *s)
+{
+	int v;
+	char *cp;
+	struct tm tm;
+
+	v = (int)strtol(s, &cp, 10);
+	if (cp != s)
+		return (v);
+	if (strptime(s, "%B", &tm) != NULL)
+		return (tm.tm_mon + 1);
+	if (strptime(s, "%b", &tm) != NULL)
+		return (tm.tm_mon + 1);
+	return (0);
+}